@mastra/factory 0.0.0-aggregate-trace-20261015182851

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 (926) hide show
  1. package/LICENSE.md +32 -0
  2. package/README.md +671 -0
  3. package/dist/auth.d.ts +201 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +623 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/boards/define-board.d.ts +111 -0
  8. package/dist/boards/define-board.d.ts.map +1 -0
  9. package/dist/boards/define-board.js +156 -0
  10. package/dist/boards/define-board.js.map +1 -0
  11. package/dist/boards/index.d.ts +14 -0
  12. package/dist/boards/index.d.ts.map +1 -0
  13. package/dist/boards/index.js +21 -0
  14. package/dist/boards/index.js.map +1 -0
  15. package/dist/boards/registry.d.ts +16 -0
  16. package/dist/boards/registry.d.ts.map +1 -0
  17. package/dist/boards/registry.js +25 -0
  18. package/dist/boards/registry.js.map +1 -0
  19. package/dist/boards/relocate.d.ts +21 -0
  20. package/dist/boards/relocate.d.ts.map +1 -0
  21. package/dist/boards/relocate.js +58 -0
  22. package/dist/boards/relocate.js.map +1 -0
  23. package/dist/boards/review.d.ts +6 -0
  24. package/dist/boards/review.d.ts.map +1 -0
  25. package/dist/boards/review.js +104 -0
  26. package/dist/boards/review.js.map +1 -0
  27. package/dist/boards/semantics.d.ts +68 -0
  28. package/dist/boards/semantics.d.ts.map +1 -0
  29. package/dist/boards/semantics.js +119 -0
  30. package/dist/boards/semantics.js.map +1 -0
  31. package/dist/boards/transition-policy.d.ts +67 -0
  32. package/dist/boards/transition-policy.d.ts.map +1 -0
  33. package/dist/boards/transition-policy.js +36 -0
  34. package/dist/boards/transition-policy.js.map +1 -0
  35. package/dist/boards/work-tool-rules.d.ts +8 -0
  36. package/dist/boards/work-tool-rules.d.ts.map +1 -0
  37. package/dist/boards/work-tool-rules.js +20 -0
  38. package/dist/boards/work-tool-rules.js.map +1 -0
  39. package/dist/boards/work-transition-policy.d.ts +3 -0
  40. package/dist/boards/work-transition-policy.d.ts.map +1 -0
  41. package/dist/boards/work-transition-policy.js +46 -0
  42. package/dist/boards/work-transition-policy.js.map +1 -0
  43. package/dist/boards/work.d.ts +4 -0
  44. package/dist/boards/work.d.ts.map +1 -0
  45. package/dist/boards/work.js +222 -0
  46. package/dist/boards/work.js.map +1 -0
  47. package/dist/capabilities/connection.d.ts +9 -0
  48. package/dist/capabilities/connection.d.ts.map +1 -0
  49. package/dist/capabilities/connection.js +1 -0
  50. package/dist/capabilities/intake.d.ts +153 -0
  51. package/dist/capabilities/intake.d.ts.map +1 -0
  52. package/dist/capabilities/intake.js +1 -0
  53. package/dist/capabilities/version-control.d.ts +268 -0
  54. package/dist/capabilities/version-control.d.ts.map +1 -0
  55. package/dist/capabilities/version-control.js +1 -0
  56. package/dist/environment/build-runner.d.ts +72 -0
  57. package/dist/environment/build-runner.d.ts.map +1 -0
  58. package/dist/environment/build-runner.js +131 -0
  59. package/dist/environment/build-runner.js.map +1 -0
  60. package/dist/environment/build-schedule.d.ts +40 -0
  61. package/dist/environment/build-schedule.d.ts.map +1 -0
  62. package/dist/environment/build-schedule.js +94 -0
  63. package/dist/environment/build-schedule.js.map +1 -0
  64. package/dist/environment/build-workflow.d.ts +62 -0
  65. package/dist/environment/build-workflow.d.ts.map +1 -0
  66. package/dist/environment/build-workflow.js +149 -0
  67. package/dist/environment/build-workflow.js.map +1 -0
  68. package/dist/environment/build.d.ts +111 -0
  69. package/dist/environment/build.d.ts.map +1 -0
  70. package/dist/environment/build.js +344 -0
  71. package/dist/environment/build.js.map +1 -0
  72. package/dist/environment/heads.d.ts +36 -0
  73. package/dist/environment/heads.d.ts.map +1 -0
  74. package/dist/environment/heads.js +60 -0
  75. package/dist/environment/heads.js.map +1 -0
  76. package/dist/factory.d.ts +225 -0
  77. package/dist/factory.d.ts.map +1 -0
  78. package/dist/factory.js +1006 -0
  79. package/dist/factory.js.map +1 -0
  80. package/dist/feed-events.d.ts +13 -0
  81. package/dist/feed-events.d.ts.map +1 -0
  82. package/dist/feed-events.js +25 -0
  83. package/dist/feed-events.js.map +1 -0
  84. package/dist/index.d.ts +22 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +15 -0
  87. package/dist/integrations/base.d.ts +302 -0
  88. package/dist/integrations/base.d.ts.map +1 -0
  89. package/dist/integrations/base.js +1 -0
  90. package/dist/integrations/github/acceptance-labels.d.ts +16 -0
  91. package/dist/integrations/github/acceptance-labels.d.ts.map +1 -0
  92. package/dist/integrations/github/acceptance-labels.js +55 -0
  93. package/dist/integrations/github/acceptance-labels.js.map +1 -0
  94. package/dist/integrations/github/app-identity.d.ts +43 -0
  95. package/dist/integrations/github/app-identity.d.ts.map +1 -0
  96. package/dist/integrations/github/app-identity.js +62 -0
  97. package/dist/integrations/github/app-identity.js.map +1 -0
  98. package/dist/integrations/github/commits.d.ts +40 -0
  99. package/dist/integrations/github/commits.d.ts.map +1 -0
  100. package/dist/integrations/github/commits.js +48 -0
  101. package/dist/integrations/github/commits.js.map +1 -0
  102. package/dist/integrations/github/config.d.ts +60 -0
  103. package/dist/integrations/github/config.d.ts.map +1 -0
  104. package/dist/integrations/github/config.js +42 -0
  105. package/dist/integrations/github/config.js.map +1 -0
  106. package/dist/integrations/github/default-rules.d.ts +218 -0
  107. package/dist/integrations/github/default-rules.d.ts.map +1 -0
  108. package/dist/integrations/github/default-rules.js +296 -0
  109. package/dist/integrations/github/default-rules.js.map +1 -0
  110. package/dist/integrations/github/integration.d.ts +270 -0
  111. package/dist/integrations/github/integration.d.ts.map +1 -0
  112. package/dist/integrations/github/integration.js +1375 -0
  113. package/dist/integrations/github/integration.js.map +1 -0
  114. package/dist/integrations/github/issue-reconciler.d.ts +28 -0
  115. package/dist/integrations/github/issue-reconciler.d.ts.map +1 -0
  116. package/dist/integrations/github/issue-reconciler.js +138 -0
  117. package/dist/integrations/github/issue-reconciler.js.map +1 -0
  118. package/dist/integrations/github/pat.d.ts +38 -0
  119. package/dist/integrations/github/pat.d.ts.map +1 -0
  120. package/dist/integrations/github/pat.js +59 -0
  121. package/dist/integrations/github/pat.js.map +1 -0
  122. package/dist/integrations/github/provenance.d.ts +34 -0
  123. package/dist/integrations/github/provenance.d.ts.map +1 -0
  124. package/dist/integrations/github/provenance.js +91 -0
  125. package/dist/integrations/github/provenance.js.map +1 -0
  126. package/dist/integrations/github/reconcile-worker.d.ts +45 -0
  127. package/dist/integrations/github/reconcile-worker.d.ts.map +1 -0
  128. package/dist/integrations/github/reconcile-worker.js +189 -0
  129. package/dist/integrations/github/reconcile-worker.js.map +1 -0
  130. package/dist/integrations/github/reconciliation-config.d.ts +3 -0
  131. package/dist/integrations/github/reconciliation-config.d.ts.map +1 -0
  132. package/dist/integrations/github/reconciliation-config.js +19 -0
  133. package/dist/integrations/github/reconciliation-config.js.map +1 -0
  134. package/dist/integrations/github/routes.d.ts +90 -0
  135. package/dist/integrations/github/routes.d.ts.map +1 -0
  136. package/dist/integrations/github/routes.js +1362 -0
  137. package/dist/integrations/github/routes.js.map +1 -0
  138. package/dist/integrations/github/rules.d.ts +173 -0
  139. package/dist/integrations/github/rules.d.ts.map +1 -0
  140. package/dist/integrations/github/rules.js +1021 -0
  141. package/dist/integrations/github/rules.js.map +1 -0
  142. package/dist/integrations/github/sandbox-release.d.ts +25 -0
  143. package/dist/integrations/github/sandbox-release.d.ts.map +1 -0
  144. package/dist/integrations/github/sandbox-release.js +38 -0
  145. package/dist/integrations/github/sandbox-release.js.map +1 -0
  146. package/dist/integrations/github/sandbox.d.ts +234 -0
  147. package/dist/integrations/github/sandbox.d.ts.map +1 -0
  148. package/dist/integrations/github/sandbox.js +947 -0
  149. package/dist/integrations/github/sandbox.js.map +1 -0
  150. package/dist/integrations/github/session-subscriptions.d.ts +28 -0
  151. package/dist/integrations/github/session-subscriptions.d.ts.map +1 -0
  152. package/dist/integrations/github/session-subscriptions.js +283 -0
  153. package/dist/integrations/github/session-subscriptions.js.map +1 -0
  154. package/dist/integrations/github/settle-or-abort.d.ts +7 -0
  155. package/dist/integrations/github/settle-or-abort.d.ts.map +1 -0
  156. package/dist/integrations/github/settle-or-abort.js +25 -0
  157. package/dist/integrations/github/settle-or-abort.js.map +1 -0
  158. package/dist/integrations/github/stale-reviews.d.ts +22 -0
  159. package/dist/integrations/github/stale-reviews.d.ts.map +1 -0
  160. package/dist/integrations/github/stale-reviews.js +70 -0
  161. package/dist/integrations/github/stale-reviews.js.map +1 -0
  162. package/dist/integrations/github/subscriptions.d.ts +54 -0
  163. package/dist/integrations/github/subscriptions.d.ts.map +1 -0
  164. package/dist/integrations/github/subscriptions.js +64 -0
  165. package/dist/integrations/github/subscriptions.js.map +1 -0
  166. package/dist/integrations/github/token-refresh.d.ts +31 -0
  167. package/dist/integrations/github/token-refresh.d.ts.map +1 -0
  168. package/dist/integrations/github/token-refresh.js +42 -0
  169. package/dist/integrations/github/token-refresh.js.map +1 -0
  170. package/dist/integrations/github/webhook.d.ts +139 -0
  171. package/dist/integrations/github/webhook.d.ts.map +1 -0
  172. package/dist/integrations/github/webhook.js +432 -0
  173. package/dist/integrations/github/webhook.js.map +1 -0
  174. package/dist/integrations/gitlab/agent-tools.d.ts +14 -0
  175. package/dist/integrations/gitlab/agent-tools.d.ts.map +1 -0
  176. package/dist/integrations/gitlab/agent-tools.js +42 -0
  177. package/dist/integrations/gitlab/agent-tools.js.map +1 -0
  178. package/dist/integrations/gitlab/api.d.ts +222 -0
  179. package/dist/integrations/gitlab/api.d.ts.map +1 -0
  180. package/dist/integrations/gitlab/api.js +274 -0
  181. package/dist/integrations/gitlab/api.js.map +1 -0
  182. package/dist/integrations/gitlab/default-rules.d.ts +125 -0
  183. package/dist/integrations/gitlab/default-rules.d.ts.map +1 -0
  184. package/dist/integrations/gitlab/default-rules.js +180 -0
  185. package/dist/integrations/gitlab/default-rules.js.map +1 -0
  186. package/dist/integrations/gitlab/integration.d.ts +138 -0
  187. package/dist/integrations/gitlab/integration.d.ts.map +1 -0
  188. package/dist/integrations/gitlab/integration.js +705 -0
  189. package/dist/integrations/gitlab/integration.js.map +1 -0
  190. package/dist/integrations/gitlab/issue-reconciler.d.ts +6 -0
  191. package/dist/integrations/gitlab/issue-reconciler.d.ts.map +1 -0
  192. package/dist/integrations/gitlab/issue-reconciler.js +123 -0
  193. package/dist/integrations/gitlab/issue-reconciler.js.map +1 -0
  194. package/dist/integrations/gitlab/merge-request-reconciler.d.ts +6 -0
  195. package/dist/integrations/gitlab/merge-request-reconciler.d.ts.map +1 -0
  196. package/dist/integrations/gitlab/merge-request-reconciler.js +267 -0
  197. package/dist/integrations/gitlab/merge-request-reconciler.js.map +1 -0
  198. package/dist/integrations/gitlab/reconciler.d.ts +5 -0
  199. package/dist/integrations/gitlab/reconciler.d.ts.map +1 -0
  200. package/dist/integrations/gitlab/reconciler.js +31 -0
  201. package/dist/integrations/gitlab/reconciler.js.map +1 -0
  202. package/dist/integrations/gitlab/reconciliation-config.d.ts +3 -0
  203. package/dist/integrations/gitlab/reconciliation-config.d.ts.map +1 -0
  204. package/dist/integrations/gitlab/reconciliation-config.js +17 -0
  205. package/dist/integrations/gitlab/reconciliation-config.js.map +1 -0
  206. package/dist/integrations/gitlab/routes.d.ts +20 -0
  207. package/dist/integrations/gitlab/routes.d.ts.map +1 -0
  208. package/dist/integrations/gitlab/routes.js +474 -0
  209. package/dist/integrations/gitlab/routes.js.map +1 -0
  210. package/dist/integrations/gitlab/rules.d.ts +35 -0
  211. package/dist/integrations/gitlab/rules.d.ts.map +1 -0
  212. package/dist/integrations/gitlab/rules.js +502 -0
  213. package/dist/integrations/gitlab/rules.js.map +1 -0
  214. package/dist/integrations/gitlab/session-subscriptions.d.ts +32 -0
  215. package/dist/integrations/gitlab/session-subscriptions.d.ts.map +1 -0
  216. package/dist/integrations/gitlab/session-subscriptions.js +193 -0
  217. package/dist/integrations/gitlab/session-subscriptions.js.map +1 -0
  218. package/dist/integrations/gitlab/subscriptions.d.ts +70 -0
  219. package/dist/integrations/gitlab/subscriptions.d.ts.map +1 -0
  220. package/dist/integrations/gitlab/subscriptions.js +76 -0
  221. package/dist/integrations/gitlab/subscriptions.js.map +1 -0
  222. package/dist/integrations/gitlab/version-control.d.ts +16 -0
  223. package/dist/integrations/gitlab/version-control.d.ts.map +1 -0
  224. package/dist/integrations/gitlab/version-control.js +621 -0
  225. package/dist/integrations/gitlab/version-control.js.map +1 -0
  226. package/dist/integrations/gitlab/webhook-dispatch.d.ts +75 -0
  227. package/dist/integrations/gitlab/webhook-dispatch.d.ts.map +1 -0
  228. package/dist/integrations/gitlab/webhook-dispatch.js +235 -0
  229. package/dist/integrations/gitlab/webhook-dispatch.js.map +1 -0
  230. package/dist/integrations/gitlab/webhook.d.ts +72 -0
  231. package/dist/integrations/gitlab/webhook.d.ts.map +1 -0
  232. package/dist/integrations/gitlab/webhook.js +201 -0
  233. package/dist/integrations/gitlab/webhook.js.map +1 -0
  234. package/dist/integrations/incidentio/agent-tools.d.ts +49 -0
  235. package/dist/integrations/incidentio/agent-tools.d.ts.map +1 -0
  236. package/dist/integrations/incidentio/agent-tools.js +90 -0
  237. package/dist/integrations/incidentio/agent-tools.js.map +1 -0
  238. package/dist/integrations/incidentio/api.d.ts +400 -0
  239. package/dist/integrations/incidentio/api.d.ts.map +1 -0
  240. package/dist/integrations/incidentio/api.js +192 -0
  241. package/dist/integrations/incidentio/api.js.map +1 -0
  242. package/dist/integrations/incidentio/claim.d.ts +8 -0
  243. package/dist/integrations/incidentio/claim.d.ts.map +1 -0
  244. package/dist/integrations/incidentio/claim.js +14 -0
  245. package/dist/integrations/incidentio/claim.js.map +1 -0
  246. package/dist/integrations/incidentio/default-rules.d.ts +46 -0
  247. package/dist/integrations/incidentio/default-rules.d.ts.map +1 -0
  248. package/dist/integrations/incidentio/default-rules.js +68 -0
  249. package/dist/integrations/incidentio/default-rules.js.map +1 -0
  250. package/dist/integrations/incidentio/intake.d.ts +10 -0
  251. package/dist/integrations/incidentio/intake.d.ts.map +1 -0
  252. package/dist/integrations/incidentio/intake.js +307 -0
  253. package/dist/integrations/incidentio/intake.js.map +1 -0
  254. package/dist/integrations/incidentio/integration.d.ts +63 -0
  255. package/dist/integrations/incidentio/integration.d.ts.map +1 -0
  256. package/dist/integrations/incidentio/integration.js +141 -0
  257. package/dist/integrations/incidentio/integration.js.map +1 -0
  258. package/dist/integrations/incidentio/issue-reconciler.d.ts +10 -0
  259. package/dist/integrations/incidentio/issue-reconciler.d.ts.map +1 -0
  260. package/dist/integrations/incidentio/issue-reconciler.js +75 -0
  261. package/dist/integrations/incidentio/issue-reconciler.js.map +1 -0
  262. package/dist/integrations/incidentio/reconciliation-config.d.ts +3 -0
  263. package/dist/integrations/incidentio/reconciliation-config.d.ts.map +1 -0
  264. package/dist/integrations/incidentio/reconciliation-config.js +17 -0
  265. package/dist/integrations/incidentio/reconciliation-config.js.map +1 -0
  266. package/dist/integrations/incidentio/routes.d.ts +76 -0
  267. package/dist/integrations/incidentio/routes.d.ts.map +1 -0
  268. package/dist/integrations/incidentio/routes.js +249 -0
  269. package/dist/integrations/incidentio/routes.js.map +1 -0
  270. package/dist/integrations/incidentio/rules.d.ts +55 -0
  271. package/dist/integrations/incidentio/rules.d.ts.map +1 -0
  272. package/dist/integrations/incidentio/rules.js +189 -0
  273. package/dist/integrations/incidentio/rules.js.map +1 -0
  274. package/dist/integrations/issue-reconcile-worker.d.ts +19 -0
  275. package/dist/integrations/issue-reconcile-worker.d.ts.map +1 -0
  276. package/dist/integrations/issue-reconcile-worker.js +97 -0
  277. package/dist/integrations/issue-reconcile-worker.js.map +1 -0
  278. package/dist/integrations/issue-reconciler.d.ts +51 -0
  279. package/dist/integrations/issue-reconciler.d.ts.map +1 -0
  280. package/dist/integrations/issue-reconciler.js +158 -0
  281. package/dist/integrations/issue-reconciler.js.map +1 -0
  282. package/dist/integrations/jira/adf.d.ts +26 -0
  283. package/dist/integrations/jira/adf.d.ts.map +1 -0
  284. package/dist/integrations/jira/adf.js +73 -0
  285. package/dist/integrations/jira/adf.js.map +1 -0
  286. package/dist/integrations/jira/agent-tools.d.ts +45 -0
  287. package/dist/integrations/jira/agent-tools.d.ts.map +1 -0
  288. package/dist/integrations/jira/agent-tools.js +87 -0
  289. package/dist/integrations/jira/agent-tools.js.map +1 -0
  290. package/dist/integrations/jira/api.d.ts +157 -0
  291. package/dist/integrations/jira/api.d.ts.map +1 -0
  292. package/dist/integrations/jira/api.js +141 -0
  293. package/dist/integrations/jira/api.js.map +1 -0
  294. package/dist/integrations/jira/claim.d.ts +9 -0
  295. package/dist/integrations/jira/claim.d.ts.map +1 -0
  296. package/dist/integrations/jira/claim.js +15 -0
  297. package/dist/integrations/jira/claim.js.map +1 -0
  298. package/dist/integrations/jira/default-rules.d.ts +47 -0
  299. package/dist/integrations/jira/default-rules.d.ts.map +1 -0
  300. package/dist/integrations/jira/default-rules.js +69 -0
  301. package/dist/integrations/jira/default-rules.js.map +1 -0
  302. package/dist/integrations/jira/integration.d.ts +114 -0
  303. package/dist/integrations/jira/integration.d.ts.map +1 -0
  304. package/dist/integrations/jira/integration.js +407 -0
  305. package/dist/integrations/jira/integration.js.map +1 -0
  306. package/dist/integrations/jira/issue-reconciler.d.ts +10 -0
  307. package/dist/integrations/jira/issue-reconciler.d.ts.map +1 -0
  308. package/dist/integrations/jira/issue-reconciler.js +70 -0
  309. package/dist/integrations/jira/issue-reconciler.js.map +1 -0
  310. package/dist/integrations/jira/reconciliation-config.d.ts +3 -0
  311. package/dist/integrations/jira/reconciliation-config.d.ts.map +1 -0
  312. package/dist/integrations/jira/reconciliation-config.js +17 -0
  313. package/dist/integrations/jira/reconciliation-config.js.map +1 -0
  314. package/dist/integrations/jira/routes.d.ts +54 -0
  315. package/dist/integrations/jira/routes.d.ts.map +1 -0
  316. package/dist/integrations/jira/routes.js +260 -0
  317. package/dist/integrations/jira/routes.js.map +1 -0
  318. package/dist/integrations/jira/rules.d.ts +57 -0
  319. package/dist/integrations/jira/rules.d.ts.map +1 -0
  320. package/dist/integrations/jira/rules.js +189 -0
  321. package/dist/integrations/jira/rules.js.map +1 -0
  322. package/dist/integrations/linear/agent-tools.d.ts +34 -0
  323. package/dist/integrations/linear/agent-tools.d.ts.map +1 -0
  324. package/dist/integrations/linear/agent-tools.js +87 -0
  325. package/dist/integrations/linear/agent-tools.js.map +1 -0
  326. package/dist/integrations/linear/claim.d.ts +8 -0
  327. package/dist/integrations/linear/claim.d.ts.map +1 -0
  328. package/dist/integrations/linear/claim.js +14 -0
  329. package/dist/integrations/linear/claim.js.map +1 -0
  330. package/dist/integrations/linear/default-rules.d.ts +46 -0
  331. package/dist/integrations/linear/default-rules.d.ts.map +1 -0
  332. package/dist/integrations/linear/default-rules.js +70 -0
  333. package/dist/integrations/linear/default-rules.js.map +1 -0
  334. package/dist/integrations/linear/integration.d.ts +260 -0
  335. package/dist/integrations/linear/integration.d.ts.map +1 -0
  336. package/dist/integrations/linear/integration.js +900 -0
  337. package/dist/integrations/linear/integration.js.map +1 -0
  338. package/dist/integrations/linear/issue-reconciler.d.ts +8 -0
  339. package/dist/integrations/linear/issue-reconciler.d.ts.map +1 -0
  340. package/dist/integrations/linear/issue-reconciler.js +73 -0
  341. package/dist/integrations/linear/issue-reconciler.js.map +1 -0
  342. package/dist/integrations/linear/reconciliation-config.d.ts +3 -0
  343. package/dist/integrations/linear/reconciliation-config.d.ts.map +1 -0
  344. package/dist/integrations/linear/reconciliation-config.js +21 -0
  345. package/dist/integrations/linear/reconciliation-config.js.map +1 -0
  346. package/dist/integrations/linear/routes.d.ts +81 -0
  347. package/dist/integrations/linear/routes.d.ts.map +1 -0
  348. package/dist/integrations/linear/routes.js +380 -0
  349. package/dist/integrations/linear/routes.js.map +1 -0
  350. package/dist/integrations/linear/rules.d.ts +54 -0
  351. package/dist/integrations/linear/rules.d.ts.map +1 -0
  352. package/dist/integrations/linear/rules.js +189 -0
  353. package/dist/integrations/linear/rules.js.map +1 -0
  354. package/dist/integrations/linear/storage.d.ts +65 -0
  355. package/dist/integrations/linear/storage.d.ts.map +1 -0
  356. package/dist/integrations/linear/storage.js +1 -0
  357. package/dist/integrations/platform/api-client.d.ts +26 -0
  358. package/dist/integrations/platform/api-client.d.ts.map +1 -0
  359. package/dist/integrations/platform/api-client.js +177 -0
  360. package/dist/integrations/platform/api-client.js.map +1 -0
  361. package/dist/integrations/platform/connect/routes.d.ts +39 -0
  362. package/dist/integrations/platform/connect/routes.d.ts.map +1 -0
  363. package/dist/integrations/platform/connect/routes.js +133 -0
  364. package/dist/integrations/platform/connect/routes.js.map +1 -0
  365. package/dist/integrations/platform/github/event-worker.d.ts +58 -0
  366. package/dist/integrations/platform/github/event-worker.d.ts.map +1 -0
  367. package/dist/integrations/platform/github/event-worker.js +449 -0
  368. package/dist/integrations/platform/github/event-worker.js.map +1 -0
  369. package/dist/integrations/platform/github/integration.d.ts +89 -0
  370. package/dist/integrations/platform/github/integration.d.ts.map +1 -0
  371. package/dist/integrations/platform/github/integration.js +1266 -0
  372. package/dist/integrations/platform/github/integration.js.map +1 -0
  373. package/dist/integrations/platform/gitlab/event-worker.d.ts +64 -0
  374. package/dist/integrations/platform/gitlab/event-worker.d.ts.map +1 -0
  375. package/dist/integrations/platform/gitlab/event-worker.js +305 -0
  376. package/dist/integrations/platform/gitlab/event-worker.js.map +1 -0
  377. package/dist/integrations/platform/gitlab/integration.d.ts +57 -0
  378. package/dist/integrations/platform/gitlab/integration.d.ts.map +1 -0
  379. package/dist/integrations/platform/gitlab/integration.js +113 -0
  380. package/dist/integrations/platform/gitlab/integration.js.map +1 -0
  381. package/dist/integrations/platform/incidentio/integration.d.ts +74 -0
  382. package/dist/integrations/platform/incidentio/integration.d.ts.map +1 -0
  383. package/dist/integrations/platform/incidentio/integration.js +406 -0
  384. package/dist/integrations/platform/incidentio/integration.js.map +1 -0
  385. package/dist/integrations/platform/jira/agent-tools.d.ts +36 -0
  386. package/dist/integrations/platform/jira/agent-tools.d.ts.map +1 -0
  387. package/dist/integrations/platform/jira/agent-tools.js +85 -0
  388. package/dist/integrations/platform/jira/agent-tools.js.map +1 -0
  389. package/dist/integrations/platform/jira/integration.d.ts +65 -0
  390. package/dist/integrations/platform/jira/integration.d.ts.map +1 -0
  391. package/dist/integrations/platform/jira/integration.js +546 -0
  392. package/dist/integrations/platform/jira/integration.js.map +1 -0
  393. package/dist/integrations/platform/jira/routes.d.ts +55 -0
  394. package/dist/integrations/platform/jira/routes.d.ts.map +1 -0
  395. package/dist/integrations/platform/jira/routes.js +274 -0
  396. package/dist/integrations/platform/jira/routes.js.map +1 -0
  397. package/dist/integrations/platform/linear/event-worker.d.ts +105 -0
  398. package/dist/integrations/platform/linear/event-worker.d.ts.map +1 -0
  399. package/dist/integrations/platform/linear/event-worker.js +379 -0
  400. package/dist/integrations/platform/linear/event-worker.js.map +1 -0
  401. package/dist/integrations/platform/linear/integration.d.ts +92 -0
  402. package/dist/integrations/platform/linear/integration.d.ts.map +1 -0
  403. package/dist/integrations/platform/linear/integration.js +754 -0
  404. package/dist/integrations/platform/linear/integration.js.map +1 -0
  405. package/dist/integrations/pull-request-head.d.ts +18 -0
  406. package/dist/integrations/pull-request-head.d.ts.map +1 -0
  407. package/dist/integrations/pull-request-head.js +45 -0
  408. package/dist/integrations/pull-request-head.js.map +1 -0
  409. package/dist/integrations/reconciliation-config.d.ts +3 -0
  410. package/dist/integrations/reconciliation-config.d.ts.map +1 -0
  411. package/dist/integrations/reconciliation-config.js +16 -0
  412. package/dist/integrations/reconciliation-config.js.map +1 -0
  413. package/dist/integrations/slack/connect-route.d.ts +46 -0
  414. package/dist/integrations/slack/connect-route.d.ts.map +1 -0
  415. package/dist/integrations/slack/connect-route.js +186 -0
  416. package/dist/integrations/slack/connect-route.js.map +1 -0
  417. package/dist/integrations/slack/emoji-shortcodes.generated.d.ts +8 -0
  418. package/dist/integrations/slack/emoji-shortcodes.generated.d.ts.map +1 -0
  419. package/dist/integrations/slack/emoji-shortcodes.generated.js +1985 -0
  420. package/dist/integrations/slack/emoji-shortcodes.generated.js.map +1 -0
  421. package/dist/integrations/slack/emoji.d.ts +3 -0
  422. package/dist/integrations/slack/emoji.d.ts.map +1 -0
  423. package/dist/integrations/slack/emoji.js +12 -0
  424. package/dist/integrations/slack/emoji.js.map +1 -0
  425. package/dist/integrations/slack/feed-publisher.d.ts +26 -0
  426. package/dist/integrations/slack/feed-publisher.d.ts.map +1 -0
  427. package/dist/integrations/slack/feed-publisher.js +44 -0
  428. package/dist/integrations/slack/feed-publisher.js.map +1 -0
  429. package/dist/integrations/slack/integration.d.ts +80 -0
  430. package/dist/integrations/slack/integration.d.ts.map +1 -0
  431. package/dist/integrations/slack/integration.js +93 -0
  432. package/dist/integrations/slack/integration.js.map +1 -0
  433. package/dist/integrations/slack/slack.d.ts +205 -0
  434. package/dist/integrations/slack/slack.d.ts.map +1 -0
  435. package/dist/integrations/slack/slack.js +653 -0
  436. package/dist/integrations/slack/slack.js.map +1 -0
  437. package/dist/integrations/subscription-session.d.ts +49 -0
  438. package/dist/integrations/subscription-session.d.ts.map +1 -0
  439. package/dist/integrations/subscription-session.js +103 -0
  440. package/dist/integrations/subscription-session.js.map +1 -0
  441. package/dist/integrations/workos/integration.d.ts +39 -0
  442. package/dist/integrations/workos/integration.d.ts.map +1 -0
  443. package/dist/integrations/workos/integration.js +91 -0
  444. package/dist/integrations/workos/integration.js.map +1 -0
  445. package/dist/packages/_internals/workspace/dist/index.js +48 -0
  446. package/dist/packages/_internals/workspace/dist/index.js.map +1 -0
  447. package/dist/platform-auth-host.d.ts +4 -0
  448. package/dist/platform-auth-host.d.ts.map +1 -0
  449. package/dist/platform-auth-host.js +18 -0
  450. package/dist/platform-auth-host.js.map +1 -0
  451. package/dist/review-verdict.d.ts +6 -0
  452. package/dist/review-verdict.d.ts.map +1 -0
  453. package/dist/review-verdict.js +14 -0
  454. package/dist/review-verdict.js.map +1 -0
  455. package/dist/routes/attention-activity.d.ts +23 -0
  456. package/dist/routes/attention-activity.d.ts.map +1 -0
  457. package/dist/routes/attention-activity.js +152 -0
  458. package/dist/routes/attention-activity.js.map +1 -0
  459. package/dist/routes/attention-parked.d.ts +22 -0
  460. package/dist/routes/attention-parked.d.ts.map +1 -0
  461. package/dist/routes/attention-parked.js +136 -0
  462. package/dist/routes/attention-parked.js.map +1 -0
  463. package/dist/routes/attention-proposed.d.ts +3 -0
  464. package/dist/routes/attention-proposed.d.ts.map +1 -0
  465. package/dist/routes/attention-proposed.js +21 -0
  466. package/dist/routes/attention-proposed.js.map +1 -0
  467. package/dist/routes/attention-providers.d.ts +159 -0
  468. package/dist/routes/attention-providers.d.ts.map +1 -0
  469. package/dist/routes/attention-providers.js +524 -0
  470. package/dist/routes/attention-providers.js.map +1 -0
  471. package/dist/routes/attention.d.ts +23 -0
  472. package/dist/routes/attention.d.ts.map +1 -0
  473. package/dist/routes/attention.js +219 -0
  474. package/dist/routes/attention.js.map +1 -0
  475. package/dist/routes/automation-runs.d.ts +37 -0
  476. package/dist/routes/automation-runs.d.ts.map +1 -0
  477. package/dist/routes/automation-runs.js +196 -0
  478. package/dist/routes/automation-runs.js.map +1 -0
  479. package/dist/routes/config.d.ts +238 -0
  480. package/dist/routes/config.d.ts.map +1 -0
  481. package/dist/routes/config.js +1011 -0
  482. package/dist/routes/config.js.map +1 -0
  483. package/dist/routes/contracts.d.ts +1080 -0
  484. package/dist/routes/contracts.d.ts.map +1 -0
  485. package/dist/routes/contracts.js +673 -0
  486. package/dist/routes/contracts.js.map +1 -0
  487. package/dist/routes/custom-provider-source.d.ts +52 -0
  488. package/dist/routes/custom-provider-source.d.ts.map +1 -0
  489. package/dist/routes/custom-provider-source.js +124 -0
  490. package/dist/routes/custom-provider-source.js.map +1 -0
  491. package/dist/routes/fs.d.ts +189 -0
  492. package/dist/routes/fs.d.ts.map +1 -0
  493. package/dist/routes/fs.js +916 -0
  494. package/dist/routes/fs.js.map +1 -0
  495. package/dist/routes/intake.d.ts +64 -0
  496. package/dist/routes/intake.d.ts.map +1 -0
  497. package/dist/routes/intake.js +627 -0
  498. package/dist/routes/intake.js.map +1 -0
  499. package/dist/routes/knowledge.d.ts +247 -0
  500. package/dist/routes/knowledge.d.ts.map +1 -0
  501. package/dist/routes/knowledge.js +1128 -0
  502. package/dist/routes/knowledge.js.map +1 -0
  503. package/dist/routes/oauth.d.ts +43 -0
  504. package/dist/routes/oauth.d.ts.map +1 -0
  505. package/dist/routes/oauth.js +477 -0
  506. package/dist/routes/oauth.js.map +1 -0
  507. package/dist/routes/projects.d.ts +68 -0
  508. package/dist/routes/projects.d.ts.map +1 -0
  509. package/dist/routes/projects.js +919 -0
  510. package/dist/routes/projects.js.map +1 -0
  511. package/dist/routes/provider-credentials.d.ts +82 -0
  512. package/dist/routes/provider-credentials.d.ts.map +1 -0
  513. package/dist/routes/provider-credentials.js +80 -0
  514. package/dist/routes/provider-credentials.js.map +1 -0
  515. package/dist/routes/route.d.ts +48 -0
  516. package/dist/routes/route.d.ts.map +1 -0
  517. package/dist/routes/route.js +15 -0
  518. package/dist/routes/route.js.map +1 -0
  519. package/dist/routes/skills.d.ts +30 -0
  520. package/dist/routes/skills.d.ts.map +1 -0
  521. package/dist/routes/skills.js +198 -0
  522. package/dist/routes/skills.js.map +1 -0
  523. package/dist/routes/source-control-sessions.d.ts +22 -0
  524. package/dist/routes/source-control-sessions.d.ts.map +1 -0
  525. package/dist/routes/source-control-sessions.js +356 -0
  526. package/dist/routes/source-control-sessions.js.map +1 -0
  527. package/dist/routes/source-control-settings.d.ts +10 -0
  528. package/dist/routes/source-control-settings.d.ts.map +1 -0
  529. package/dist/routes/source-control-settings.js +87 -0
  530. package/dist/routes/source-control-settings.js.map +1 -0
  531. package/dist/routes/supervisor.d.ts +25 -0
  532. package/dist/routes/supervisor.d.ts.map +1 -0
  533. package/dist/routes/supervisor.js +35 -0
  534. package/dist/routes/supervisor.js.map +1 -0
  535. package/dist/routes/surface.d.ts +133 -0
  536. package/dist/routes/surface.d.ts.map +1 -0
  537. package/dist/routes/surface.js +518 -0
  538. package/dist/routes/surface.js.map +1 -0
  539. package/dist/routes/telemetry.d.ts +13 -0
  540. package/dist/routes/telemetry.d.ts.map +1 -0
  541. package/dist/routes/telemetry.js +60 -0
  542. package/dist/routes/telemetry.js.map +1 -0
  543. package/dist/routes/tenant-credentials.d.ts +87 -0
  544. package/dist/routes/tenant-credentials.d.ts.map +1 -0
  545. package/dist/routes/tenant-credentials.js +219 -0
  546. package/dist/routes/tenant-credentials.js.map +1 -0
  547. package/dist/routes/work-items.d.ts +49 -0
  548. package/dist/routes/work-items.d.ts.map +1 -0
  549. package/dist/routes/work-items.js +633 -0
  550. package/dist/routes/work-items.js.map +1 -0
  551. package/dist/rules/binding-context.d.ts +59 -0
  552. package/dist/rules/binding-context.d.ts.map +1 -0
  553. package/dist/rules/binding-context.js +134 -0
  554. package/dist/rules/binding-context.js.map +1 -0
  555. package/dist/rules/decision-applicability.d.ts +32 -0
  556. package/dist/rules/decision-applicability.d.ts.map +1 -0
  557. package/dist/rules/decision-applicability.js +56 -0
  558. package/dist/rules/decision-applicability.js.map +1 -0
  559. package/dist/rules/dispatch-errors.d.ts +13 -0
  560. package/dist/rules/dispatch-errors.d.ts.map +1 -0
  561. package/dist/rules/dispatch-errors.js +105 -0
  562. package/dist/rules/dispatch-errors.js.map +1 -0
  563. package/dist/rules/dispatcher.d.ts +86 -0
  564. package/dist/rules/dispatcher.d.ts.map +1 -0
  565. package/dist/rules/dispatcher.js +1159 -0
  566. package/dist/rules/dispatcher.js.map +1 -0
  567. package/dist/rules/event-rules.d.ts +23 -0
  568. package/dist/rules/event-rules.d.ts.map +1 -0
  569. package/dist/rules/event-rules.js +46 -0
  570. package/dist/rules/event-rules.js.map +1 -0
  571. package/dist/rules/index.d.ts +6 -0
  572. package/dist/rules/index.d.ts.map +1 -0
  573. package/dist/rules/index.js +4 -0
  574. package/dist/rules/processor.d.ts +90 -0
  575. package/dist/rules/processor.d.ts.map +1 -0
  576. package/dist/rules/processor.js +486 -0
  577. package/dist/rules/processor.js.map +1 -0
  578. package/dist/rules/resolve.d.ts +15 -0
  579. package/dist/rules/resolve.d.ts.map +1 -0
  580. package/dist/rules/resolve.js +23 -0
  581. package/dist/rules/resolve.js.map +1 -0
  582. package/dist/rules/review-source-tool.d.ts +105 -0
  583. package/dist/rules/review-source-tool.d.ts.map +1 -0
  584. package/dist/rules/review-source-tool.js +109 -0
  585. package/dist/rules/review-source-tool.js.map +1 -0
  586. package/dist/rules/start-coordinator.d.ts +64 -0
  587. package/dist/rules/start-coordinator.d.ts.map +1 -0
  588. package/dist/rules/start-coordinator.js +246 -0
  589. package/dist/rules/start-coordinator.js.map +1 -0
  590. package/dist/rules/terminal-cleanup.d.ts +38 -0
  591. package/dist/rules/terminal-cleanup.d.ts.map +1 -0
  592. package/dist/rules/terminal-cleanup.js +68 -0
  593. package/dist/rules/terminal-cleanup.js.map +1 -0
  594. package/dist/rules/tools.d.ts +15 -0
  595. package/dist/rules/tools.d.ts.map +1 -0
  596. package/dist/rules/tools.js +185 -0
  597. package/dist/rules/tools.js.map +1 -0
  598. package/dist/rules/transition-service.d.ts +93 -0
  599. package/dist/rules/transition-service.d.ts.map +1 -0
  600. package/dist/rules/transition-service.js +402 -0
  601. package/dist/rules/transition-service.js.map +1 -0
  602. package/dist/rules/types.d.ts +553 -0
  603. package/dist/rules/types.d.ts.map +1 -0
  604. package/dist/rules/types.js +154 -0
  605. package/dist/rules/types.js.map +1 -0
  606. package/dist/rules/validation.d.ts +21 -0
  607. package/dist/rules/validation.d.ts.map +1 -0
  608. package/dist/rules/validation.js +327 -0
  609. package/dist/rules/validation.js.map +1 -0
  610. package/dist/sandbox/callback-factory-sandbox.d.ts +15 -0
  611. package/dist/sandbox/callback-factory-sandbox.d.ts.map +1 -0
  612. package/dist/sandbox/callback-factory-sandbox.js +22 -0
  613. package/dist/sandbox/callback-factory-sandbox.js.map +1 -0
  614. package/dist/sandbox/git-ref.d.ts +7 -0
  615. package/dist/sandbox/git-ref.d.ts.map +1 -0
  616. package/dist/sandbox/git-ref.js +15 -0
  617. package/dist/sandbox/git-ref.js.map +1 -0
  618. package/dist/sandbox/local-factory-sandbox.d.ts +20 -0
  619. package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -0
  620. package/dist/sandbox/local-factory-sandbox.js +27 -0
  621. package/dist/sandbox/local-factory-sandbox.js.map +1 -0
  622. package/dist/sandbox/materialization.d.ts +41 -0
  623. package/dist/sandbox/materialization.d.ts.map +1 -0
  624. package/dist/sandbox/materialization.js +18 -0
  625. package/dist/sandbox/materialization.js.map +1 -0
  626. package/dist/sandbox/session-retirement.d.ts +45 -0
  627. package/dist/sandbox/session-retirement.d.ts.map +1 -0
  628. package/dist/sandbox/session-retirement.js +153 -0
  629. package/dist/sandbox/session-retirement.js.map +1 -0
  630. package/dist/sandbox/session-sandbox.d.ts +185 -0
  631. package/dist/sandbox/session-sandbox.d.ts.map +1 -0
  632. package/dist/sandbox/session-sandbox.js +248 -0
  633. package/dist/sandbox/session-sandbox.js.map +1 -0
  634. package/dist/sandbox/workdir.d.ts +45 -0
  635. package/dist/sandbox/workdir.d.ts.map +1 -0
  636. package/dist/sandbox/workdir.js +64 -0
  637. package/dist/sandbox/workdir.js.map +1 -0
  638. package/dist/secret-encryption.d.ts +25 -0
  639. package/dist/secret-encryption.d.ts.map +1 -0
  640. package/dist/secret-encryption.js +107 -0
  641. package/dist/secret-encryption.js.map +1 -0
  642. package/dist/server-error.d.ts +12 -0
  643. package/dist/server-error.d.ts.map +1 -0
  644. package/dist/server-error.js +16 -0
  645. package/dist/server-error.js.map +1 -0
  646. package/dist/session/credential-policy.d.ts +20 -0
  647. package/dist/session/credential-policy.d.ts.map +1 -0
  648. package/dist/session/credential-policy.js +70 -0
  649. package/dist/session/credential-policy.js.map +1 -0
  650. package/dist/session/default-model-hydration.d.ts +46 -0
  651. package/dist/session/default-model-hydration.d.ts.map +1 -0
  652. package/dist/session/default-model-hydration.js +85 -0
  653. package/dist/session/default-model-hydration.js.map +1 -0
  654. package/dist/session/environment-repositories.d.ts +31 -0
  655. package/dist/session/environment-repositories.d.ts.map +1 -0
  656. package/dist/session/environment-repositories.js +89 -0
  657. package/dist/session/environment-repositories.js.map +1 -0
  658. package/dist/session/environment-state-processor.d.ts +59 -0
  659. package/dist/session/environment-state-processor.d.ts.map +1 -0
  660. package/dist/session/environment-state-processor.js +105 -0
  661. package/dist/session/environment-state-processor.js.map +1 -0
  662. package/dist/session/factory-session.d.ts +159 -0
  663. package/dist/session/factory-session.d.ts.map +1 -0
  664. package/dist/session/factory-session.js +226 -0
  665. package/dist/session/factory-session.js.map +1 -0
  666. package/dist/session/filesystem-capture.d.ts +50 -0
  667. package/dist/session/filesystem-capture.d.ts.map +1 -0
  668. package/dist/session/filesystem-capture.js +231 -0
  669. package/dist/session/filesystem-capture.js.map +1 -0
  670. package/dist/session/first-exec-capture.d.ts +38 -0
  671. package/dist/session/first-exec-capture.d.ts.map +1 -0
  672. package/dist/session/first-exec-capture.js +91 -0
  673. package/dist/session/first-exec-capture.js.map +1 -0
  674. package/dist/session/first-message-capture.d.ts +33 -0
  675. package/dist/session/first-message-capture.d.ts.map +1 -0
  676. package/dist/session/first-message-capture.js +35 -0
  677. package/dist/session/first-message-capture.js.map +1 -0
  678. package/dist/session/live-sessions.d.ts +63 -0
  679. package/dist/session/live-sessions.d.ts.map +1 -0
  680. package/dist/session/live-sessions.js +90 -0
  681. package/dist/session/live-sessions.js.map +1 -0
  682. package/dist/session/memory-settings-hydration.d.ts +36 -0
  683. package/dist/session/memory-settings-hydration.d.ts.map +1 -0
  684. package/dist/session/memory-settings-hydration.js +43 -0
  685. package/dist/session/memory-settings-hydration.js.map +1 -0
  686. package/dist/session/org-seed.d.ts +67 -0
  687. package/dist/session/org-seed.d.ts.map +1 -0
  688. package/dist/session/org-seed.js +53 -0
  689. package/dist/session/org-seed.js.map +1 -0
  690. package/dist/session/run-audit.d.ts +54 -0
  691. package/dist/session/run-audit.d.ts.map +1 -0
  692. package/dist/session/run-audit.js +124 -0
  693. package/dist/session/run-audit.js.map +1 -0
  694. package/dist/session/session-title.d.ts +7 -0
  695. package/dist/session/session-title.d.ts.map +1 -0
  696. package/dist/session/session-title.js +14 -0
  697. package/dist/session/session-title.js.map +1 -0
  698. package/dist/session/shell-commands.d.ts +5 -0
  699. package/dist/session/shell-commands.d.ts.map +1 -0
  700. package/dist/session/shell-commands.js +25 -0
  701. package/dist/session/shell-commands.js.map +1 -0
  702. package/dist/session/source-control-tools.d.ts +25 -0
  703. package/dist/session/source-control-tools.d.ts.map +1 -0
  704. package/dist/session/source-control-tools.js +594 -0
  705. package/dist/session/source-control-tools.js.map +1 -0
  706. package/dist/session/thread-title-mirror.d.ts +35 -0
  707. package/dist/session/thread-title-mirror.d.ts.map +1 -0
  708. package/dist/session/thread-title-mirror.js +51 -0
  709. package/dist/session/thread-title-mirror.js.map +1 -0
  710. package/dist/session/work-item-repository.d.ts +21 -0
  711. package/dist/session/work-item-repository.d.ts.map +1 -0
  712. package/dist/session/work-item-repository.js +113 -0
  713. package/dist/session/work-item-repository.js.map +1 -0
  714. package/dist/skills/catalog.d.ts +14 -0
  715. package/dist/skills/catalog.d.ts.map +1 -0
  716. package/dist/skills/catalog.js +62 -0
  717. package/dist/skills/catalog.js.map +1 -0
  718. package/dist/skills/service.d.ts +70 -0
  719. package/dist/skills/service.d.ts.map +1 -0
  720. package/dist/skills/service.js +88 -0
  721. package/dist/skills/service.js.map +1 -0
  722. package/dist/spa-static.d.ts +33 -0
  723. package/dist/spa-static.d.ts.map +1 -0
  724. package/dist/spa-static.js +104 -0
  725. package/dist/spa-static.js.map +1 -0
  726. package/dist/state-signing.d.ts +59 -0
  727. package/dist/state-signing.d.ts.map +1 -0
  728. package/dist/state-signing.js +83 -0
  729. package/dist/state-signing.js.map +1 -0
  730. package/dist/storage/domains/audit/actions.d.ts +24 -0
  731. package/dist/storage/domains/audit/actions.d.ts.map +1 -0
  732. package/dist/storage/domains/audit/actions.js +69 -0
  733. package/dist/storage/domains/audit/actions.js.map +1 -0
  734. package/dist/storage/domains/audit/actors.d.ts +5 -0
  735. package/dist/storage/domains/audit/actors.d.ts.map +1 -0
  736. package/dist/storage/domains/audit/actors.js +25 -0
  737. package/dist/storage/domains/audit/actors.js.map +1 -0
  738. package/dist/storage/domains/audit/agent-audit.d.ts +30 -0
  739. package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -0
  740. package/dist/storage/domains/audit/agent-audit.js +93 -0
  741. package/dist/storage/domains/audit/agent-audit.js.map +1 -0
  742. package/dist/storage/domains/audit/base.d.ts +133 -0
  743. package/dist/storage/domains/audit/base.d.ts.map +1 -0
  744. package/dist/storage/domains/audit/base.js +206 -0
  745. package/dist/storage/domains/audit/base.js.map +1 -0
  746. package/dist/storage/domains/audit/domain.d.ts +79 -0
  747. package/dist/storage/domains/audit/domain.d.ts.map +1 -0
  748. package/dist/storage/domains/audit/domain.js +248 -0
  749. package/dist/storage/domains/audit/domain.js.map +1 -0
  750. package/dist/storage/domains/audit/wire.d.ts +24 -0
  751. package/dist/storage/domains/audit/wire.d.ts.map +1 -0
  752. package/dist/storage/domains/audit/wire.js +16 -0
  753. package/dist/storage/domains/audit/wire.js.map +1 -0
  754. package/dist/storage/domains/channel-identity/base.d.ts +100 -0
  755. package/dist/storage/domains/channel-identity/base.d.ts.map +1 -0
  756. package/dist/storage/domains/channel-identity/base.js +164 -0
  757. package/dist/storage/domains/channel-identity/base.js.map +1 -0
  758. package/dist/storage/domains/comments/activity.d.ts +40 -0
  759. package/dist/storage/domains/comments/activity.d.ts.map +1 -0
  760. package/dist/storage/domains/comments/activity.js +94 -0
  761. package/dist/storage/domains/comments/activity.js.map +1 -0
  762. package/dist/storage/domains/comments/actor.d.ts +51 -0
  763. package/dist/storage/domains/comments/actor.d.ts.map +1 -0
  764. package/dist/storage/domains/comments/actor.js +38 -0
  765. package/dist/storage/domains/comments/actor.js.map +1 -0
  766. package/dist/storage/domains/comments/base.d.ts +245 -0
  767. package/dist/storage/domains/comments/base.d.ts.map +1 -0
  768. package/dist/storage/domains/comments/base.js +533 -0
  769. package/dist/storage/domains/comments/base.js.map +1 -0
  770. package/dist/storage/domains/comments/domain.d.ts +135 -0
  771. package/dist/storage/domains/comments/domain.d.ts.map +1 -0
  772. package/dist/storage/domains/comments/domain.js +285 -0
  773. package/dist/storage/domains/comments/domain.js.map +1 -0
  774. package/dist/storage/domains/comments/feed-context.d.ts +22 -0
  775. package/dist/storage/domains/comments/feed-context.d.ts.map +1 -0
  776. package/dist/storage/domains/comments/feed-context.js +89 -0
  777. package/dist/storage/domains/comments/feed-context.js.map +1 -0
  778. package/dist/storage/domains/comments/feed-sync.d.ts +21 -0
  779. package/dist/storage/domains/comments/feed-sync.d.ts.map +1 -0
  780. package/dist/storage/domains/comments/feed-sync.js +1 -0
  781. package/dist/storage/domains/comments/parse.d.ts +23 -0
  782. package/dist/storage/domains/comments/parse.d.ts.map +1 -0
  783. package/dist/storage/domains/comments/parse.js +90 -0
  784. package/dist/storage/domains/comments/parse.js.map +1 -0
  785. package/dist/storage/domains/comments/routes.d.ts +24 -0
  786. package/dist/storage/domains/comments/routes.d.ts.map +1 -0
  787. package/dist/storage/domains/comments/routes.js +302 -0
  788. package/dist/storage/domains/comments/routes.js.map +1 -0
  789. package/dist/storage/domains/comments/schema.d.ts +5 -0
  790. package/dist/storage/domains/comments/schema.d.ts.map +1 -0
  791. package/dist/storage/domains/comments/schema.js +179 -0
  792. package/dist/storage/domains/comments/schema.js.map +1 -0
  793. package/dist/storage/domains/comments/wire.d.ts +40 -0
  794. package/dist/storage/domains/comments/wire.d.ts.map +1 -0
  795. package/dist/storage/domains/comments/wire.js +37 -0
  796. package/dist/storage/domains/comments/wire.js.map +1 -0
  797. package/dist/storage/domains/credentials/base.d.ts +136 -0
  798. package/dist/storage/domains/credentials/base.d.ts.map +1 -0
  799. package/dist/storage/domains/credentials/base.js +294 -0
  800. package/dist/storage/domains/credentials/base.js.map +1 -0
  801. package/dist/storage/domains/custom-providers/base.d.ts +59 -0
  802. package/dist/storage/domains/custom-providers/base.d.ts.map +1 -0
  803. package/dist/storage/domains/custom-providers/base.js +176 -0
  804. package/dist/storage/domains/custom-providers/base.js.map +1 -0
  805. package/dist/storage/domains/filesystem/base.d.ts +26 -0
  806. package/dist/storage/domains/filesystem/base.d.ts.map +1 -0
  807. package/dist/storage/domains/filesystem/base.js +74 -0
  808. package/dist/storage/domains/filesystem/base.js.map +1 -0
  809. package/dist/storage/domains/intake/base.d.ts +150 -0
  810. package/dist/storage/domains/intake/base.d.ts.map +1 -0
  811. package/dist/storage/domains/intake/base.js +431 -0
  812. package/dist/storage/domains/intake/base.js.map +1 -0
  813. package/dist/storage/domains/integrations/base.d.ts +128 -0
  814. package/dist/storage/domains/integrations/base.d.ts.map +1 -0
  815. package/dist/storage/domains/integrations/base.js +333 -0
  816. package/dist/storage/domains/integrations/base.js.map +1 -0
  817. package/dist/storage/domains/memory-settings/base.d.ts +58 -0
  818. package/dist/storage/domains/memory-settings/base.d.ts.map +1 -0
  819. package/dist/storage/domains/memory-settings/base.js +129 -0
  820. package/dist/storage/domains/memory-settings/base.js.map +1 -0
  821. package/dist/storage/domains/model-defaults/base.d.ts +29 -0
  822. package/dist/storage/domains/model-defaults/base.d.ts.map +1 -0
  823. package/dist/storage/domains/model-defaults/base.js +79 -0
  824. package/dist/storage/domains/model-defaults/base.js.map +1 -0
  825. package/dist/storage/domains/projects/base.d.ts +191 -0
  826. package/dist/storage/domains/projects/base.d.ts.map +1 -0
  827. package/dist/storage/domains/projects/base.js +352 -0
  828. package/dist/storage/domains/projects/base.js.map +1 -0
  829. package/dist/storage/domains/queue-health/base.d.ts +52 -0
  830. package/dist/storage/domains/queue-health/base.d.ts.map +1 -0
  831. package/dist/storage/domains/queue-health/base.js +122 -0
  832. package/dist/storage/domains/queue-health/base.js.map +1 -0
  833. package/dist/storage/domains/source-control/base.d.ts +422 -0
  834. package/dist/storage/domains/source-control/base.d.ts.map +1 -0
  835. package/dist/storage/domains/source-control/base.js +1114 -0
  836. package/dist/storage/domains/source-control/base.js.map +1 -0
  837. package/dist/storage/domains/source-control/inmemory.d.ts +147 -0
  838. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -0
  839. package/dist/storage/domains/source-control/inmemory.js +416 -0
  840. package/dist/storage/domains/source-control/inmemory.js.map +1 -0
  841. package/dist/storage/domains/work-items/base.d.ts +794 -0
  842. package/dist/storage/domains/work-items/base.d.ts.map +1 -0
  843. package/dist/storage/domains/work-items/base.js +2747 -0
  844. package/dist/storage/domains/work-items/base.js.map +1 -0
  845. package/dist/storage/domains/work-items/board-version.d.ts +26 -0
  846. package/dist/storage/domains/work-items/board-version.d.ts.map +1 -0
  847. package/dist/storage/domains/work-items/board-version.js +110 -0
  848. package/dist/storage/domains/work-items/board-version.js.map +1 -0
  849. package/dist/storage/domains/work-items/metrics.d.ts +97 -0
  850. package/dist/storage/domains/work-items/metrics.d.ts.map +1 -0
  851. package/dist/storage/domains/work-items/metrics.js +226 -0
  852. package/dist/storage/domains/work-items/metrics.js.map +1 -0
  853. package/dist/supervisor/health-worker.d.ts +19 -0
  854. package/dist/supervisor/health-worker.d.ts.map +1 -0
  855. package/dist/supervisor/health-worker.js +74 -0
  856. package/dist/supervisor/health-worker.js.map +1 -0
  857. package/dist/supervisor/health.d.ts +79 -0
  858. package/dist/supervisor/health.d.ts.map +1 -0
  859. package/dist/supervisor/health.js +228 -0
  860. package/dist/supervisor/health.js.map +1 -0
  861. package/dist/supervisor/instructions.d.ts +6 -0
  862. package/dist/supervisor/instructions.d.ts.map +1 -0
  863. package/dist/supervisor/instructions.js +66 -0
  864. package/dist/supervisor/instructions.js.map +1 -0
  865. package/dist/supervisor/read-tools.d.ts +43 -0
  866. package/dist/supervisor/read-tools.d.ts.map +1 -0
  867. package/dist/supervisor/read-tools.js +343 -0
  868. package/dist/supervisor/read-tools.js.map +1 -0
  869. package/dist/supervisor/session-messaging.d.ts +26 -0
  870. package/dist/supervisor/session-messaging.d.ts.map +1 -0
  871. package/dist/supervisor/session-messaging.js +21 -0
  872. package/dist/supervisor/session-messaging.js.map +1 -0
  873. package/dist/supervisor/session.d.ts +38 -0
  874. package/dist/supervisor/session.d.ts.map +1 -0
  875. package/dist/supervisor/session.js +79 -0
  876. package/dist/supervisor/session.js.map +1 -0
  877. package/dist/supervisor/write-tools.d.ts +30 -0
  878. package/dist/supervisor/write-tools.d.ts.map +1 -0
  879. package/dist/supervisor/write-tools.js +231 -0
  880. package/dist/supervisor/write-tools.js.map +1 -0
  881. package/dist/telemetry-types.d.ts +7 -0
  882. package/dist/telemetry-types.d.ts.map +1 -0
  883. package/dist/telemetry-types.js +24 -0
  884. package/dist/telemetry-types.js.map +1 -0
  885. package/dist/telemetry.d.ts +9 -0
  886. package/dist/telemetry.d.ts.map +1 -0
  887. package/dist/telemetry.js +47 -0
  888. package/dist/telemetry.js.map +1 -0
  889. package/dist/timing.d.ts +15 -0
  890. package/dist/timing.d.ts.map +1 -0
  891. package/dist/timing.js +34 -0
  892. package/dist/timing.js.map +1 -0
  893. package/dist/work-item-branch.d.ts +33 -0
  894. package/dist/work-item-branch.d.ts.map +1 -0
  895. package/dist/work-item-branch.js +70 -0
  896. package/dist/work-item-branch.js.map +1 -0
  897. package/dist/workspace.d.ts +131 -0
  898. package/dist/workspace.d.ts.map +1 -0
  899. package/dist/workspace.js +995 -0
  900. package/dist/workspace.js.map +1 -0
  901. package/factory-skills/configure-factory-rules/SKILL.md +122 -0
  902. package/factory-skills/factory-complete-issue/SKILL.md +24 -0
  903. package/factory-skills/factory-gitlab-rereview/SKILL.md +22 -0
  904. package/factory-skills/factory-gitlab-review/SKILL.md +48 -0
  905. package/factory-skills/factory-plan/SKILL.md +72 -0
  906. package/factory-skills/factory-rereview/SKILL.md +225 -0
  907. package/factory-skills/factory-review/SKILL.md +214 -0
  908. package/factory-skills/factory-review/references/archaeology.md +225 -0
  909. package/factory-skills/factory-review/references/categories/README.md +34 -0
  910. package/factory-skills/factory-review/references/categories/behavior-change.md +36 -0
  911. package/factory-skills/factory-review/references/categories/bug-fix.md +37 -0
  912. package/factory-skills/factory-review/references/categories/docs.md +32 -0
  913. package/factory-skills/factory-review/references/categories/experimental-flagged.md +34 -0
  914. package/factory-skills/factory-review/references/categories/infra-tooling.md +37 -0
  915. package/factory-skills/factory-review/references/categories/internal-capability.md +35 -0
  916. package/factory-skills/factory-review/references/categories/large-cross-cutting.md +35 -0
  917. package/factory-skills/factory-review/references/categories/mechanical.md +36 -0
  918. package/factory-skills/factory-review/references/categories/performance.md +33 -0
  919. package/factory-skills/factory-review/references/categories/public-api.md +38 -0
  920. package/factory-skills/factory-review/references/categories/refactor.md +35 -0
  921. package/factory-skills/factory-review/references/categories/revert.md +31 -0
  922. package/factory-skills/factory-review/references/categories/schema-storage.md +39 -0
  923. package/factory-skills/factory-review/references/categories/security.md +35 -0
  924. package/factory-skills/factory-review/references/categories/tests-only.md +38 -0
  925. package/factory-skills/factory-triage/SKILL.md +197 -0
  926. package/package.json +92 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","names":["#intakeTarget","#relocateLabeledIssue","#relatedItem","#handOffPush","#ingestProject","#factoryMentionTarget","#isFactoryLogin","#linkedClosureItem","#resolveItem"],"sources":["../../../src/integrations/github/rules.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\n\nimport {\n boardEventHandlers,\n boardForWorkItem,\n eventBoardId,\n rulePhaseField,\n withBoardClosure,\n workItemPhaseSemantics,\n} from '../../boards/index.js';\nimport type { BoardRegistry } from '../../boards/index.js';\nimport { cardLabels, moveCardToBoard } from '../../boards/relocate.js';\nimport { selectEventRule } from '../../rules/event-rules.js';\nimport type {\n FactoryGithubEventName,\n FactoryGithubRuleContext,\n FactoryRuleActor,\n FactoryRuleDecision,\n} from '../../rules/types.js';\nimport { assertFactoryDecisionTarget, validateFactoryRuleDecisions } from '../../rules/validation.js';\nimport { resolveIntakeLabelRoute } from '../../storage/domains/intake/base.js';\nimport type { IntakeStorage } from '../../storage/domains/intake/base.js';\nimport type { IntegrationStorageHandle } from '../../storage/domains/integrations/base.js';\nimport type { FactoryProjectsStorage } from '../../storage/domains/projects/base.js';\nimport type {\n ExternalRepositoryProjectTarget,\n SourceControlStorageHandle,\n} from '../../storage/domains/source-control/base.js';\nimport type { WorkItemRow, WorkItemsStorage } from '../../storage/domains/work-items/base.js';\nimport {\n FACTORY_PULL_REQUEST_RECONCILIATION_KEY,\n WorkItemUpdateConflictError,\n} from '../../storage/domains/work-items/base.js';\nimport type { IntegrationContext, IntegrationHooks } from '../base.js';\nimport { recordPullRequestHead } from '../pull-request-head.js';\nimport type { GithubAppIdentity } from './app-identity.js';\nimport type { GithubEventRules } from './default-rules.js';\nimport type { GithubRepositoryPermission } from './integration.js';\nimport { changeRequestTargetKey } from './subscriptions.js';\nimport type { ParsedGithubWebhook } from './webhook.js';\n\nconst TRUSTED_PERMISSIONS = new Set(['write', 'admin']);\nconst RULE_TIMEOUT_MS = 5_000;\nconst FACTORY_TRIAGE_COMMENT_MARKER = '<!-- mastra-factory-triage -->';\n\nasync function withRuleTimeout<T>(promise: Promise<T>): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => reject(new Error('FACTORY_RULE_TIMEOUT')), RULE_TIMEOUT_MS);\n }),\n ]);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nfunction object(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction timestamp(value: unknown): number | undefined {\n const parsed = typeof value === 'string' ? Date.parse(value) : NaN;\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n\nfunction string(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction number(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction boolean(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\nfunction actorLogins(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap(actor => {\n const login = string(object(actor)?.login);\n return login ? [login] : [];\n });\n}\n\nfunction sameLabels(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((label, index) => label === b[index]);\n}\n\nfunction labelNames(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap(label => {\n if (typeof label === 'string') return label ? [label] : [];\n const name = string(object(label)?.name);\n return name ? [name] : [];\n });\n}\n\nfunction parseFactoryReviewCommand(\n body: string | undefined,\n target: string | undefined,\n): { command: 'review' | 're-review'; target: string } | undefined {\n if (!body || !target) return undefined;\n const firstLine = body\n .split('\\n')\n .map(line => line.trim())\n .find(line => line.length > 0)\n ?.toLowerCase();\n if (!firstLine) return undefined;\n const mention = `@${target.toLowerCase().replace(/\\[bot\\]$/, '')}`;\n if (firstLine === `${mention} review`) return { command: 'review', target };\n if (firstLine === `${mention} re-review`) return { command: 're-review', target };\n return undefined;\n}\n\nfunction eventName(parsed: ParsedGithubWebhook): FactoryGithubEventName | undefined {\n const action = string(parsed.payload.action);\n if (parsed.event === 'issues' && action === 'opened') return 'issueOpened';\n if (parsed.event === 'issues' && action === 'edited') {\n const changes = object(parsed.payload.changes);\n return object(changes?.title) || object(changes?.body) ? 'issueEdited' : undefined;\n }\n if (parsed.event === 'issues' && action === 'closed') return 'issueClosed';\n if (parsed.event === 'issue_comment') {\n const issue = object(parsed.payload.issue);\n // A comment on a PR arrives as `issue_comment` with `issue.pull_request` set.\n // It routes to the PR's own event so it binds to the authoring Work item via\n // provenance instead of being mistaken for a comment on an issue of the same\n // number. Only `created` matters: edits and deletions of an existing comment\n // are not new feedback to act on.\n if (object(issue?.pull_request)) {\n return action === 'created' ? 'pullRequestCommentCreated' : undefined;\n }\n if (action === 'created') return 'issueCommentCreated';\n if (action === 'edited') return 'issueCommentEdited';\n if (action === 'deleted') return 'issueCommentDeleted';\n }\n if (parsed.event === 'pull_request' && action === 'opened') return 'pullRequestOpened';\n if (parsed.event === 'pull_request' && action === 'synchronize') return 'pullRequestUpdated';\n if (parsed.event === 'pull_request' && action === 'closed') {\n return boolean(object(parsed.payload.pull_request)?.merged) ? 'pullRequestMerged' : 'pullRequestClosed';\n }\n if (parsed.event === 'pull_request' && action === 'review_requested') return 'pullRequestReviewRequested';\n if (parsed.event === 'pull_request_review' && action === 'submitted') return 'pullRequestReviewSubmitted';\n return undefined;\n}\n\n/**\n * Canonical source keys (`github-issue:N`, `github-pr:N`) do not identify a\n * repository, so a project linked to several repositories could bind repo A's\n * event to repo B's same-numbered card. The card's intake-stamped URL is\n * authoritative; the intake-stamped `githubRepositoryId` covers URL-less\n * cards. A card with neither signal cannot be attributed by number alone.\n */\nconst MAX_STALE_RULE_ATTEMPTS = 3;\n\nexport function cardBelongsToRepository(item: WorkItemRow, repositoryId: number, repositoryFullName: string): boolean {\n const url = item.externalSource?.url;\n if (url) {\n const match = /^https?:\\/\\/[^/]+\\/(.+)\\/(?:issues|pull)\\/\\d+(?:[/?#]|$)/.exec(url);\n if (match && match[1] === repositoryFullName) return true;\n }\n // A renamed repository leaves the old owner/name in the card URL, so a URL\n // mismatch still defers to the stable intake-stamped repository id.\n return item.metadata?.githubRepositoryId === repositoryId;\n}\n\nfunction canonicalSourceKey(kind: 'issue' | 'pull-request', itemNumber: number): string {\n return kind === 'issue' ? `github-issue:${itemNumber}` : `github-pr:${itemNumber}`;\n}\n\nfunction legacySourceKey(repositoryId: number, kind: 'issue' | 'pull-request', itemNumber: number): string {\n return `github:${repositoryId}:${kind}:${itemNumber}`;\n}\n\nfunction provenanceTarget(repositoryId: number, pullRequestNumber: number): string {\n return `factory-pr-provenance:${repositoryId}:${pullRequestNumber}`;\n}\n\nfunction workItemSource(item: WorkItemRow) {\n if (!item.externalSource) return 'manual' as const;\n return item.externalSource.type === 'pull-request' ? ('github-pr' as const) : ('github-issue' as const);\n}\n\nfunction workItemSourceKey(item: WorkItemRow): string | null {\n return item.externalSource?.externalId ?? null;\n}\n\n// Throws on a failed lookup: callers writing permanent state must retry, not\n// record the failure as distrust.\nexport async function trustedCollaborator(\n github: GithubRulesIntegration,\n input: { installationId: number; repository: string; login: string },\n): Promise<boolean> {\n const permission = await github.getRepositoryCollaboratorPermission(\n input.installationId,\n input.repository,\n input.login,\n );\n return permission !== undefined && TRUSTED_PERMISSIONS.has(permission);\n}\n\n// Terminal cards leave the reconcile loop below, so the ones that got there before author\n// trust was recorded have no other path to an answer.\nfunction authorAwaitingTrust(item: WorkItemRow, repository: ReconcileRepository): string | undefined {\n const metadata = item.metadata ?? {};\n if (typeof metadata.author !== 'string' || metadata.authorTrusted !== undefined) return undefined;\n const tracked = reconcilablePullRequestNumber(item, repository) ?? reconcilableIssueNumber(item, repository);\n if (tracked === undefined) return undefined;\n // A canonical key with no URL names no repository, and the pull request matcher takes it anyway.\n // Asking GitHub about the wrong repository of a multi-repository project would record a wrong answer.\n const unattributed =\n !item.externalSource?.url && /^github-(?:pr|issue):\\d+$/.test(item.externalSource?.externalId ?? '');\n if (unattributed && metadata.githubRepositoryId !== repository.id) return undefined;\n return metadata.author;\n}\n\nexport function sweepTrustLookup(\n github: GithubRulesIntegration,\n repository: ReconcileRepository,\n): (login: string) => Promise<boolean> {\n const cache = new Map<string, boolean>();\n return async login => {\n const cached = cache.get(login);\n if (cached !== undefined) return cached;\n const trusted = await trustedCollaborator(github, {\n installationId: repository.installationId,\n repository: repository.fullName,\n login,\n });\n cache.set(login, trusted);\n return trusted;\n };\n}\n\nasync function githubActor(\n github: GithubRulesIntegration,\n input: { installationId: number; repository: string; login: string; factoryAuthored: boolean },\n): Promise<FactoryRuleActor> {\n // The actor bit is recomputed on every event, so a failed lookup can read\n // untrusted for this one delivery instead of failing the ingest.\n const trusted = await trustedCollaborator(github, input).catch(() => false);\n return { type: 'github', login: input.login, trusted, factoryAuthored: input.factoryAuthored };\n}\n\ninterface FactoryPullRequestProvenanceData {\n kind: 'factory-pr-provenance';\n workItemId: string;\n}\n\nfunction pullRequestProvenance(\n data: Record<string, unknown> | undefined,\n factoryProjectId: string,\n): FactoryPullRequestProvenanceData | null {\n if (!data || data.kind !== 'factory-pr-provenance' || typeof data.workItemId !== 'string') return null;\n // Provenance proves which Factory *project's* run authored the PR. A row\n // written by a sibling project in the same org — or a legacy row without the\n // project stamp — fails closed here: honoring it would brand the PR\n // Factory-authored in a project that never touched it, and auto-start a\n // review that checks out and executes the PR there.\n if (data.factoryProjectId !== factoryProjectId) return null;\n return { kind: 'factory-pr-provenance', workItemId: data.workItemId };\n}\n\nexport interface GithubRulesIntegration {\n readonly rules: GithubEventRules;\n readonly slug?: string;\n /**\n * Factory's own GitHub login, used to ignore its own writes. Optional because\n * not every integration can name itself; when absent, self-recognition falls\n * back to the configured slug and, failing that, to content Factory stamps\n * itself (see `FACTORY_TRIAGE_COMMENT_MARKER`).\n */\n readonly identity?: GithubAppIdentity;\n getRepositoryCollaboratorPermission(\n installationId: number,\n repoFullName: string,\n username: string,\n ): Promise<GithubRepositoryPermission | undefined>;\n}\n\nexport interface GithubRulesOptions {\n github: GithubRulesIntegration;\n sourceControl: SourceControlStorageHandle;\n /** Integration-scoped storage; provenance rows are validated at read. */\n integrationStorage: IntegrationStorageHandle;\n projects: FactoryProjectsStorage;\n storage: WorkItemsStorage;\n configVersion: string;\n boards: BoardRegistry;\n /**\n * Decides which installed board an issue lands on: a label route first, then the repository's\n * intake source binding. Absent means Work.\n */\n intake?: Pick<IntakeStorage, 'listLabelRoutes' | 'listBindings'>;\n /** Hands a push to a linked repository off for an environment build. */\n onRepositoryPush?: IntegrationHooks['onRepositoryPush'];\n}\n\n/** Identity under which label-driven relocations are recorded. */\nconst LABEL_ROUTE_USER_ID = 'factory-rule-dispatcher';\n\nfunction issueLabelChange(parsed: ParsedGithubWebhook): boolean {\n const action = string(parsed.payload.action);\n return parsed.event === 'issues' && (action === 'labeled' || action === 'unlabeled');\n}\n\n/**\n * Whether a login is Factory itself. Prefers the resolved identity, which is\n * observed from Factory's own writes, and falls back to the configured slug.\n */\nexport function isFactoryGithubLogin(\n github: Pick<GithubRulesIntegration, 'identity' | 'slug'>,\n login: string | null | undefined,\n): boolean {\n if (github.identity?.known) return github.identity.matches(login);\n const slug = github.slug?.trim();\n if (!slug || !login) return false;\n return login.toLowerCase() === `${slug.toLowerCase()}[bot]`;\n}\n\nexport class GithubRules {\n constructor(private readonly options: GithubRulesOptions) {}\n\n /**\n * Whether a login is Factory itself. Prefers the resolved identity, which is\n * observed from Factory's own writes, and falls back to the configured slug.\n * An unset slug must not silently answer \"not Factory\" — that is what\n * disabled every self-loop guard.\n */\n #isFactoryLogin(login: string | undefined): boolean {\n return isFactoryGithubLogin(this.options.github, login);\n }\n\n #factoryMentionTarget(): string | undefined {\n const identity = this.options.github.identity;\n if (identity?.known) return identity.login;\n const slug = this.options.github.slug?.trim();\n return slug ? `${slug.toLowerCase()}[bot]` : undefined;\n }\n\n /**\n * Board an issue lands on: the one its labels select under the project's label routes, else the\n * board the repository's intake source binding names. Only installed boards count. Undefined\n * leaves built-in routing (Work) in charge.\n */\n async #intakeTarget(\n project: ExternalRepositoryProjectTarget,\n repositoryName: string,\n labels: readonly string[],\n ): Promise<{ board: string; initialPhase: string } | undefined> {\n const intake = this.options.intake;\n if (!intake) return undefined;\n const { orgId, factoryProjectId } = project;\n if (labels.length > 0) {\n const routes = await intake.listLabelRoutes({ orgId, factoryProjectId, integrationId: 'github' });\n const route = resolveIntakeLabelRoute(routes, labels);\n const board = route ? this.options.boards.get(route.board) : undefined;\n if (board) return { board: board.id, initialPhase: board.initialPhase };\n }\n // GitHub bindings are keyed by the internal repository id; the slug is accepted too since the\n // bindings API stores whatever source id it is given.\n const slug = repositoryName.toLowerCase();\n const binding = (await intake.listBindings({ orgId, integrationId: 'github' })).find(\n candidate =>\n candidate.factoryProjectId === factoryProjectId &&\n (candidate.sourceId === project.projectRepository.repositoryId || candidate.sourceId.toLowerCase() === slug),\n );\n const board = binding?.board ? this.options.boards.get(binding.board) : undefined;\n return board ? { board: board.id, initialPhase: board.initialPhase } : undefined;\n }\n\n /**\n * `labeled` / `unlabeled` are not rule events: the labels only decide which board the card belongs\n * on, so the card is re-routed here and its label metadata refreshed. Cards a run owns, and\n * finished cards, stay where they are.\n */\n async #relocateLabeledIssue(\n parsed: ParsedGithubWebhook,\n repositoryId: number,\n repositoryName: string,\n project: ExternalRepositoryProjectTarget,\n ): Promise<{ status: 'ignored' | 'committed' }> {\n const issue = object(parsed.payload.issue);\n const issueNumber = issue?.pull_request === undefined ? number(issue?.number) : undefined;\n if (!issueNumber) return { status: 'ignored' };\n const found = await this.#relatedItem(\n project.orgId,\n project.factoryProjectId,\n repositoryId,\n repositoryName,\n issueNumber,\n undefined,\n undefined,\n null,\n );\n if (!found || found.externalSource?.type !== 'issue') return { status: 'ignored' };\n const labels = labelNames(issue?.labels);\n let item = found;\n let changed = false;\n if (!sameLabels(cardLabels(item), labels)) {\n let updated;\n try {\n updated = await this.options.storage.update({\n orgId: item.orgId,\n id: item.id,\n userId: LABEL_ROUTE_USER_ID,\n patch: { metadata: { ...(item.metadata ?? {}), labels } },\n expectedRevision: item.revision,\n });\n } catch (error) {\n // The card changed under us (a run wrote it, or a concurrent delivery won). The next\n // delivery or reconcile pass carries the same labels, so drop this one instead of 5xx-ing.\n if (!(error instanceof WorkItemUpdateConflictError)) throw error;\n return { status: 'ignored' };\n }\n if (!updated) return { status: 'ignored' };\n item = updated.item;\n changed = true;\n }\n const target = await this.#intakeTarget(project, repositoryName, labels);\n const outcome = await moveCardToBoard({\n workItems: this.options.storage,\n boardRegistry: this.options.boards,\n userId: LABEL_ROUTE_USER_ID,\n item,\n targetBoard: target?.board ?? 'work',\n });\n return { status: changed || outcome === 'moved' ? 'committed' : 'ignored' };\n }\n\n async ingest(parsed: ParsedGithubWebhook): Promise<{ status: 'ignored' | 'committed' | 'replayed' | 'missing' }> {\n const event = eventName(parsed);\n const labelChange = issueLabelChange(parsed);\n const repository = object(parsed.payload.repository);\n const installationId = number(object(parsed.payload.installation)?.id);\n const repositoryId = number(repository?.id);\n const repositoryName = string(repository?.full_name);\n const login = string(object(parsed.payload.sender)?.login);\n if (parsed.event === 'push' && installationId && repositoryId) {\n await this.#handOffPush(parsed, installationId, repositoryId);\n return { status: 'ignored' };\n }\n if ((!event && !labelChange) || !installationId || !repositoryId || !repositoryName || !login) {\n return { status: 'ignored' };\n }\n\n const projects = await this.options.sourceControl.projectRepositories.listByExternalRepository({\n installationExternalId: String(installationId),\n repositoryExternalId: String(repositoryId),\n });\n if (projects.length === 0) return { status: 'ignored' };\n const results = [];\n for (const project of projects) {\n results.push(\n event\n ? await this.#ingestProject(parsed, event, installationId, repositoryId, repositoryName, login, project)\n : await this.#relocateLabeledIssue(parsed, repositoryId, repositoryName, project),\n );\n }\n if (results.some(result => result.status === 'committed')) return { status: 'committed' };\n if (results.some(result => result.status === 'replayed')) return { status: 'replayed' };\n return results[0] ?? { status: 'ignored' };\n }\n\n /**\n * A push is not a work-item event; it only reaches the environment build\n * hand-off, once per project the repository is linked to. The hook decides\n * whether the project builds on push.\n */\n async #handOffPush(parsed: ParsedGithubWebhook, installationId: number, repositoryId: number): Promise<void> {\n const onRepositoryPush = this.options.onRepositoryPush;\n const ref = string(parsed.payload.ref);\n const defaultBranch = string(object(parsed.payload.repository)?.default_branch);\n if (!onRepositoryPush || !ref || !defaultBranch) return;\n const projects = await this.options.sourceControl.projectRepositories.listByExternalRepository({\n installationExternalId: String(installationId),\n repositoryExternalId: String(repositoryId),\n });\n for (const project of projects) {\n onRepositoryPush({\n orgId: project.orgId,\n factoryProjectId: project.factoryProjectId,\n projectRepository: {\n id: project.projectRepository.id,\n inEnvironment: project.projectRepository.inEnvironment,\n },\n ref,\n defaultBranch,\n });\n }\n }\n\n async #ingestProject(\n parsed: ParsedGithubWebhook,\n event: FactoryGithubEventName,\n installationId: number,\n repositoryId: number,\n repositoryName: string,\n login: string,\n project: ExternalRepositoryProjectTarget,\n ): Promise<{ status: 'ignored' | 'committed' | 'replayed' | 'missing' }> {\n const factoryProject = await this.options.projects.get({\n orgId: project.orgId,\n id: project.factoryProjectId,\n });\n if (!factoryProject) return { status: 'missing' };\n const issue = object(parsed.payload.issue);\n const issueComment = object(parsed.payload.comment);\n const changes = object(parsed.payload.changes);\n // A comment on a PR carries the PR under `issue` (with `pull_request` set)\n // and has no `pull_request` payload of its own. Read the PR from `issue` in\n // that case so provenance and `context.pullRequest` behave as they do for\n // every other PR event, and so the number is never treated as an issue's.\n const commentOnPullRequest = object(parsed.payload.issue)?.pull_request !== undefined;\n const pullRequest = object(parsed.payload.pull_request) ?? (commentOnPullRequest ? issue : undefined);\n const issueNumber = commentOnPullRequest ? undefined : number(issue?.number);\n const pullRequestNumber = number(pullRequest?.number);\n const provenance = pullRequestNumber\n ? pullRequestProvenance(\n (\n await this.options.integrationStorage.subscriptions.listByTarget(\n provenanceTarget(repositoryId, pullRequestNumber),\n { status: 'active' },\n )\n ).find(\n subscription =>\n subscription.orgId === project.orgId && subscription.data?.factoryProjectId === project.factoryProjectId,\n )?.data,\n project.factoryProjectId,\n )\n : null;\n // Re-review events target the PR's own Review card, not the Work item that\n // provenance would otherwise bind the event to. For review_requested the\n // sender is whoever clicked re-request, so a Factory-authored PR must not\n // brand a human requester as factory-authored.\n const reviewRequested = event === 'pullRequestReviewRequested';\n const reviewCommand =\n event === 'pullRequestCommentCreated'\n ? parseFactoryReviewCommand(string(issueComment?.body), this.#factoryMentionTarget())\n : undefined;\n const reviewEntryRequested = reviewRequested || reviewCommand !== undefined;\n // Provenance proves the *pull request* came from Factory, which is not the\n // same as the sender of this event. For events where the sender is whoever\n // reacted to the PR — re-requesting review, commenting, submitting a review\n // — branding them from provenance would mark every human and every review\n // bot as Factory. Only the app login identifies Factory for those.\n const senderIsResponder =\n reviewRequested || event === 'pullRequestCommentCreated' || event === 'pullRequestReviewSubmitted';\n const reReviewEvent = reviewEntryRequested || event === 'pullRequestUpdated';\n const requestedReviewer = string(object(parsed.payload.requested_reviewer)?.login);\n const pullRequestAuthor = string(object(pullRequest?.user)?.login);\n const pullRequestFactoryAuthored = provenance !== null || this.#isFactoryLogin(pullRequestAuthor);\n const resolvedItem = await this.#relatedItem(\n project.orgId,\n project.factoryProjectId,\n repositoryId,\n repositoryName,\n issueNumber,\n pullRequestNumber,\n string(object(pullRequest?.head)?.ref),\n reReviewEvent ? null : provenance,\n senderIsResponder && !reviewEntryRequested,\n );\n // A review-entry request must never treat a branch-matched authoring Work\n // card as the PR's Review card. A missing Review card is materialized below.\n const relatedItem =\n reviewEntryRequested && resolvedItem?.externalSource?.type !== 'pull-request' ? undefined : resolvedItem;\n const intake = issueNumber\n ? await this.#intakeTarget(project, repositoryName, labelNames(issue?.labels))\n : undefined;\n const actor = await githubActor(this.options.github, {\n installationId,\n repository: repositoryName,\n login,\n factoryAuthored: (!senderIsResponder && provenance !== null) || this.#isFactoryLogin(login),\n });\n // A marked handoff comment is ignored only when Factory authored it: a\n // human may quote the marker to add an investigation lead, and that must\n // still retrigger triage. Recognising the author is therefore the whole\n // guard — when identity cannot be resolved this fails open and Factory's\n // own handoff cancels the run that wrote it.\n if (\n actor.type === 'github' &&\n actor.factoryAuthored &&\n (event === 'issueCommentCreated' || event === 'issueCommentEdited') &&\n string(issueComment?.body)?.includes(FACTORY_TRIAGE_COMMENT_MARKER)\n ) {\n return { status: 'ignored' };\n }\n // One delivery can concern two cards — a merged pull request settles both\n // its own Review card and the Work item that authored it — and every\n // decision a rule returns is committed against a single item, at that\n // item's revision. So the evaluation, not the decision, is what fans out:\n // the rule runs once per bound item, each with its own ingress identity.\n const evaluate = async (\n item: WorkItemRow | undefined,\n ingressIdentity: string,\n /** Set on the evaluation that files the pull request's own Review card. */\n pullRequestIntake = false,\n attempt = 1,\n ): Promise<{ status: 'ignored' | 'committed' | 'replayed' | 'missing' }> => {\n const context: FactoryGithubRuleContext = {\n tenant: { orgId: project.orgId, projectId: project.factoryProjectId },\n actor,\n ingress: { type: 'github', id: ingressIdentity },\n cause: `github.${event}`,\n causalChain: [],\n configVersion: this.options.configVersion,\n ...(item\n ? {\n item: {\n id: item.id,\n source: workItemSource(item),\n sourceKey: workItemSourceKey(item),\n parentWorkItemId: item.parentWorkItemId,\n title: item.title,\n url: item.externalSource?.url ?? null,\n stages: item.stages,\n acceptedAt: item.acceptedAt,\n metadata: item.metadata,\n },\n board: boardForWorkItem(item),\n itemRevision: item.revision,\n ...withBoardClosure(this.options.boards, item),\n ...rulePhaseField(this.options.boards, item),\n }\n : {}),\n ...(intake ? { intake } : {}),\n ...(pullRequestIntake ? { pullRequestIntake: true } : {}),\n event,\n deliveryId: parsed.deliveryId,\n factory: { createdAt: factoryProject.createdAt.toISOString() },\n repository: { id: repositoryId, fullName: repositoryName, installationId },\n ...(issueNumber && string(issue?.title) && string(issue?.html_url)\n ? {\n issue: {\n number: issueNumber,\n title: string(issue?.title)!,\n url: string(issue?.html_url)!,\n ...(string(issue?.created_at) ? { createdAt: string(issue?.created_at) } : {}),\n ...(string(issue?.updated_at) ? { updatedAt: string(issue?.updated_at) } : {}),\n assignees: actorLogins(issue?.assignees),\n labels: labelNames(issue?.labels),\n ...(string(issue?.state) === 'closed' || string(issue?.state) === 'open'\n ? { state: string(issue?.state) as 'open' | 'closed' }\n : {}),\n ...(string(issue?.state_reason) ? { stateReason: string(issue?.state_reason) } : {}),\n },\n }\n : {}),\n ...(event === 'issueEdited'\n ? { issueChange: { title: Boolean(object(changes?.title)), body: Boolean(object(changes?.body)) } }\n : {}),\n ...(number(issueComment?.id)\n ? {\n issueComment: {\n id: number(issueComment?.id)!,\n ...(string(issueComment?.body) ? { body: string(issueComment?.body) } : {}),\n ...(string(issueComment?.html_url) ? { url: string(issueComment?.html_url) } : {}),\n ...(string(object(issueComment?.user)?.login)\n ? { author: string(object(issueComment?.user)?.login) }\n : {}),\n ...(string(object(issueComment?.user)?.type)\n ? { authorType: string(object(issueComment?.user)?.type) }\n : {}),\n ...(string(issueComment?.created_at) ? { createdAt: string(issueComment?.created_at) } : {}),\n ...(string(issueComment?.updated_at) ? { updatedAt: string(issueComment?.updated_at) } : {}),\n },\n }\n : {}),\n ...(pullRequestNumber && string(pullRequest?.title) && string(pullRequest?.html_url)\n ? {\n pullRequest: {\n number: pullRequestNumber,\n title: string(pullRequest?.title)!,\n url: string(pullRequest?.html_url)!,\n ...(string(pullRequest?.created_at) ? { createdAt: string(pullRequest?.created_at) } : {}),\n state: string(pullRequest?.state) === 'closed' ? ('closed' as const) : ('open' as const),\n draft: boolean(pullRequest?.draft) ?? false,\n merged: boolean(pullRequest?.merged) ?? false,\n assignees: actorLogins(pullRequest?.assignees),\n requestedReviewers: actorLogins(pullRequest?.requested_reviewers),\n labels: labelNames(pullRequest?.labels),\n ...(pullRequestAuthor ? { author: pullRequestAuthor } : {}),\n factoryAuthored: pullRequestFactoryAuthored,\n headBranch: string(object(pullRequest?.head)?.ref) ?? '',\n baseBranch: string(object(pullRequest?.base)?.ref) ?? '',\n },\n }\n : {}),\n ...(reviewRequested && requestedReviewer\n ? {\n reviewRequest: {\n reviewer: requestedReviewer,\n factoryReviewer: this.#isFactoryLogin(requestedReviewer),\n },\n }\n : {}),\n ...(reviewCommand ? { reviewCommand } : {}),\n ...(object(parsed.payload.review)\n ? {\n review: {\n id: number(object(parsed.payload.review)?.id) ?? 0,\n state: string(object(parsed.payload.review)?.state) ?? 'unknown',\n url: string(object(parsed.payload.review)?.html_url) ?? '',\n ...(string(object(object(parsed.payload.review)?.user)?.login)\n ? { author: string(object(object(parsed.payload.review)?.user)?.login) }\n : {}),\n ...(string(object(parsed.payload.review)?.body)\n ? { body: string(object(parsed.payload.review)?.body) }\n : {}),\n },\n }\n : {}),\n };\n\n const rule = selectEventRule(\n this.options.github.rules,\n boardEventHandlers(this.options.boards, eventBoardId(context), 'github'),\n event,\n );\n let decision: FactoryRuleDecision | void;\n let decisions: Record<string, unknown>[] = [];\n let outcome: { status: 'accepted' | 'rejected'; code?: string; reason?: string } = { status: 'accepted' };\n try {\n decision = rule ? await withRuleTimeout(Promise.resolve(rule(Object.freeze(context)))) : undefined;\n if (decision?.type === 'reject') {\n outcome = { status: 'rejected', code: decision.code, reason: decision.reason };\n } else if (decision) {\n decisions = validateFactoryRuleDecisions([decision]).map(entry => {\n assertFactoryDecisionTarget(entry, this.options.boards, item ? boardForWorkItem(item) : undefined);\n return { ...entry };\n });\n }\n } catch (error) {\n const timedOut = error instanceof Error && error.message === 'FACTORY_RULE_TIMEOUT';\n outcome = {\n status: 'rejected',\n code: timedOut ? 'timeout' : 'rule_error',\n reason: timedOut\n ? 'Factory rule evaluation timed out.'\n : error instanceof Error\n ? error.message.slice(0, 2_000)\n : 'Factory GitHub rule failed.',\n };\n }\n\n const committed = await this.options.storage.commitRuleEvaluation({\n orgId: project.orgId,\n factoryProjectId: project.factoryProjectId,\n workItemId: item?.id ?? null,\n ingress: { identity: ingressIdentity, triggerType: `github.${event}` },\n configVersion: this.options.configVersion,\n expectedRevision: item?.revision ?? null,\n actor: { ...actor },\n outcome,\n decisions,\n causalChain: [],\n now: new Date(),\n });\n if (committed.status === 'stale') {\n // The item was written concurrently. Re-read it and run the rule again\n // against the fresh revision; nothing was persisted for this attempt.\n if (attempt >= MAX_STALE_RULE_ATTEMPTS) {\n throw new Error(`Factory GitHub rule evaluation for ${ingressIdentity} kept losing revision races.`);\n }\n const fresh = item ? await this.options.storage.get({ orgId: project.orgId, id: item.id }) : null;\n if (item && !fresh) return { status: 'missing' };\n return evaluate(fresh ?? undefined, ingressIdentity, pullRequestIntake, attempt + 1);\n }\n return { status: committed.status };\n };\n\n const deliveryIdentity = `${installationId}:${parsed.deliveryId}`;\n // A pull request opening concerns two cards: its own Review card, which the\n // arrival rule files — committed against the Work item that authored the\n // pull request when one exists, because that binding is what links the two\n // — and that authoring item, which is now out for review. The arrival is\n // the delivery's own evaluation; the item's is a second one, under an\n // identity suffixed with its id, because ingress identities are the replay\n // key and reusing the delivery's own would drop it as a duplicate.\n const pullRequestOpened = event === 'pullRequestOpened';\n const primary = await evaluate(relatedItem, deliveryIdentity, pullRequestOpened);\n // A closed pull request is the one *other* event both linked cards need:\n // the Review card has to close, and the Work item that wrote the code has\n // to finish (on merge) or at least stop recording it as open. Resolution binds the delivery to\n // whichever card it matched first, so evaluate the other one too.\n const linked =\n (event === 'pullRequestMerged' || event === 'pullRequestClosed') && relatedItem && pullRequestNumber\n ? await this.#linkedClosureItem(\n project.orgId,\n project.factoryProjectId,\n repositoryId,\n repositoryName,\n pullRequestNumber,\n relatedItem,\n )\n : undefined;\n // Moving the card to Done does not touch its pull request fields, so without\n // this the card reads \"open\" until the next sweep and still offers Re-review.\n // Stamped after the evaluations, which commit at the revision they read.\n const stampClosed = async (companionStatus?: string) => {\n if (!pullRequestNumber) return;\n // The authoring Work item records which pull request it has out, so an\n // agent cannot close the work while that pull request is still open.\n if (pullRequestOpened) {\n // Mirrors the out-for-review rule's trust gate. A replayed opened\n // delivery only restores the mark (after a failed write) while the\n // pull request's Review card still records it open, so a redelivery\n // after the close cannot block the Work item again.\n const trusted = (actor.type === 'github' && actor.trusted) || pullRequestFactoryAuthored;\n const reviewCard =\n authoringItem && trusted\n ? await this.#linkedClosureItem(\n project.orgId,\n project.factoryProjectId,\n repositoryId,\n repositoryName,\n pullRequestNumber,\n authoringItem,\n )\n : undefined;\n const stillOpen =\n companionStatus === 'replayed'\n ? reviewCard !== undefined && reviewCard.metadata?.state !== 'closed'\n : reviewCard?.metadata?.state !== 'closed';\n if (authoringItem && trusted && stillOpen) {\n // The head comes along so a head recorded for an earlier pull\n // request cannot mark this one's verdict outdated. A replayed opening\n // of the pull request already recorded keeps the head its pushes left.\n const rebinding = authoringItem.metadata?.openPullRequestNumber !== pullRequestNumber;\n const head = rebinding\n ? {\n pullRequestHeadSha: string(object(pullRequest?.head)?.sha)?.toLowerCase() ?? null,\n pullRequestHeadAt: timestamp(pullRequest?.updated_at) ?? null,\n }\n : {};\n await this.options.storage.update({\n orgId: authoringItem.orgId,\n id: authoringItem.id,\n userId: 'factory-rule-dispatcher',\n patch: { metadata: { openPullRequestNumber: pullRequestNumber, ...head } },\n });\n }\n return;\n }\n if (event !== 'pullRequestMerged' && event !== 'pullRequestClosed') return;\n for (const card of [relatedItem, linked]) {\n if (!card) continue;\n if (card.externalSource?.type !== 'pull-request') {\n // A merge settles the review, so the authoring Work item's mirrored\n // \"request changes\" no longer stops it from being closed.\n // Only the pull request the card has out settles it; an older one\n // merging must not clear a verdict that belongs to its successor.\n const recorded = card.metadata?.openPullRequestNumber;\n const ownsCard = typeof recorded !== 'number' || recorded === pullRequestNumber;\n const settled = {\n ...(ownsCard && event === 'pullRequestMerged' && typeof card.metadata?.reviewVerdict === 'string'\n ? { reviewVerdict: null }\n : {}),\n ...(recorded === pullRequestNumber ? { openPullRequestNumber: null } : {}),\n };\n if (Object.keys(settled).length > 0) {\n await this.options.storage.update({\n orgId: card.orgId,\n id: card.id,\n userId: 'factory-rule-dispatcher',\n patch: { metadata: settled },\n });\n }\n continue;\n }\n await this.options.storage.update({\n orgId: card.orgId,\n id: card.id,\n userId: 'factory-rule-dispatcher',\n patch: { metadata: { state: 'closed', merged: event === 'pullRequestMerged' } },\n });\n }\n };\n const authoringItem =\n linked === undefined &&\n pullRequestOpened &&\n relatedItem !== undefined &&\n relatedItem.externalSource?.type !== 'pull-request'\n ? relatedItem\n : undefined;\n // A push moves the head a recorded review verdict was given on. Recording\n // the new head lets the verdict badge show that it is outdated, while the\n // verdict itself stays so the next pass still runs as a re-review.\n const stampHead = async () => {\n const headSha = string(object(pullRequest?.head)?.sha)?.toLowerCase();\n if (event !== 'pullRequestUpdated' || !headSha || !pullRequestNumber) return;\n const headAt = timestamp(pullRequest?.updated_at);\n if (relatedItem?.externalSource?.type !== 'pull-request') return;\n const parent = await this.#linkedClosureItem(\n project.orgId,\n project.factoryProjectId,\n repositoryId,\n repositoryName,\n pullRequestNumber,\n relatedItem,\n );\n // The authoring Work item mirrors the verdict of the pull request it has\n // out; a push to an older one must not mark its successor's verdict.\n await recordPullRequestHead(this.options.storage, {\n orgId: relatedItem.orgId,\n id: relatedItem.id,\n headSha,\n headAt,\n });\n if (parent) {\n await recordPullRequestHead(this.options.storage, {\n orgId: parent.orgId,\n id: parent.id,\n headSha,\n headAt,\n ownedPullRequestNumber: pullRequestNumber,\n });\n }\n };\n if (linked === undefined && authoringItem === undefined) {\n await stampClosed();\n await stampHead();\n return primary;\n }\n const companion = linked ?? authoringItem;\n const secondary = await evaluate(companion, `${deliveryIdentity}:${companion?.id ?? 'pull-request'}`);\n await stampClosed(secondary.status);\n for (const status of ['committed', 'replayed'] as const) {\n if (primary.status === status || secondary.status === status) return { status };\n }\n return primary;\n }\n\n /**\n * The other card a closed pull request concerns, joined through the Review\n * card's `parentWorkItemId` — the link `upsertLinkedWorkItem` records when the\n * pull request is opened, and therefore an exact join that needs no branch\n * heuristics. Returns nothing when the pull request has only one card, which\n * is every pull request Factory did not open from a work item's session.\n */\n async #linkedClosureItem(\n orgId: string,\n projectId: string,\n repositoryId: number,\n repositoryFullName: string,\n pullRequestNumber: number,\n resolved: WorkItemRow,\n ): Promise<WorkItemRow | undefined> {\n const items = await this.options.storage.list({ orgId, factoryProjectId: projectId });\n const linked =\n resolved.externalSource?.type === 'pull-request'\n ? // Bound to the pull request's own Review card: follow the recorded\n // link back to the work item that authored it.\n items.find(item => item.id === resolved.parentWorkItemId)\n : // Bound to the work item (provenance): find the Review card this pull\n // request opened, and only when it names this item as its parent — a\n // card for the same number in another repository is not this one's.\n items.find(\n item =>\n item.parentWorkItemId === resolved.id &&\n (item.externalSource?.externalId === canonicalSourceKey('pull-request', pullRequestNumber) ||\n item.externalSource?.externalId === legacySourceKey(repositoryId, 'pull-request', pullRequestNumber)) &&\n cardBelongsToRepository(item, repositoryId, repositoryFullName),\n );\n return linked?.id === resolved.id ? undefined : linked;\n }\n\n async #relatedItem(\n orgId: string,\n projectId: string,\n repositoryId: number,\n repositoryFullName: string,\n issueNumber: number | undefined,\n pullRequestNumber: number | undefined,\n pullRequestHeadBranch: string | undefined,\n provenance: FactoryPullRequestProvenanceData | null,\n preferAuthoringItem = false,\n ): Promise<WorkItemRow | undefined> {\n const items = await this.options.storage.list({ orgId, factoryProjectId: projectId });\n const resolved = this.#resolveItem(\n items,\n repositoryId,\n repositoryFullName,\n issueNumber,\n pullRequestNumber,\n pullRequestHeadBranch,\n provenance,\n );\n // Feedback on a pull request has to reach the item that *wrote* the code.\n // Provenance normally lands it there directly, but when provenance is\n // missing the PR-number lookup wins and returns the PR's own Review card\n // instead — a board the feedback rules deliberately refuse to act on, so\n // the wake is silently dropped. The linked card records its author in\n // `parentWorkItemId`, so follow that link back rather than relaxing the\n // guard, which would let a Review card react to its own posted review.\n if (preferAuthoringItem && resolved?.externalSource?.type === 'pull-request' && resolved.parentWorkItemId) {\n return items.find(item => item.id === resolved.parentWorkItemId) ?? resolved;\n }\n return resolved;\n }\n\n #resolveItem(\n items: WorkItemRow[],\n repositoryId: number,\n repositoryFullName: string,\n issueNumber: number | undefined,\n pullRequestNumber: number | undefined,\n pullRequestHeadBranch: string | undefined,\n provenance: FactoryPullRequestProvenanceData | null,\n ): WorkItemRow | undefined {\n if (provenance) return items.find(item => item.id === provenance.workItemId);\n if (issueNumber) {\n return (\n items.find(\n item =>\n item.externalSource?.externalId === canonicalSourceKey('issue', issueNumber) &&\n cardBelongsToRepository(item, repositoryId, repositoryFullName),\n ) ?? items.find(item => item.externalSource?.externalId === legacySourceKey(repositoryId, 'issue', issueNumber))\n );\n }\n if (pullRequestNumber) {\n return (\n items.find(\n item =>\n item.externalSource?.externalId === canonicalSourceKey('pull-request', pullRequestNumber) &&\n cardBelongsToRepository(item, repositoryId, repositoryFullName),\n ) ??\n items.find(\n item => item.externalSource?.externalId === legacySourceKey(repositoryId, 'pull-request', pullRequestNumber),\n ) ??\n // Provenance fallback: a PR pushed from a work item's session branch\n // belongs to that item even when no gh-pr-create provenance was\n // recorded (session predating state seeding, or the PR was opened\n // outside the tracked tool call). Session branches are per-item\n // (`factory/issue-N`), so a head-branch match is unambiguous.\n (pullRequestHeadBranch\n ? items.find(\n item =>\n item.externalSource?.type !== 'pull-request' &&\n Object.values(item.sessions).some(session => session.branch === pullRequestHeadBranch),\n )\n : undefined)\n );\n }\n return undefined;\n }\n}\n\nexport interface ReconcilePullRequestState {\n title: string;\n url: string;\n state: 'open' | 'closed';\n draft: boolean;\n merged: boolean;\n assignees?: string[];\n requestedReviewers?: string[];\n labels?: string[];\n headBranch: string;\n baseBranch: string;\n author?: string;\n createdAt?: string;\n mergedBy?: string;\n}\n\nexport interface PolledPullRequestState extends ReconcilePullRequestState {\n createdAt: string;\n}\n\nexport type GithubPullRequestFetcher = (input: {\n installationId: number;\n repository: string;\n number: number;\n}) => Promise<ReconcilePullRequestState | undefined>;\n\nexport interface ReconcileIssueState {\n title: string;\n url: string;\n state: 'open' | 'closed';\n /** GitHub close reason: `completed`, `not_planned`, or `duplicate`. */\n stateReason?: string;\n assignees?: string[];\n labels?: string[];\n author?: string;\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport type GithubIssueFetcher = (input: {\n installationId: number;\n repository: string;\n number: number;\n}) => Promise<ReconcileIssueState | undefined>;\n\n/** Lists a repository's open issues (pull requests excluded) for missed-open discovery. */\nexport type GithubOpenIssueLister = (input: {\n installationId: number;\n repository: string;\n}) => Promise<Array<ReconcileIssueState & { number: number }>>;\n\nexport interface ReconcileRepository {\n id: number;\n fullName: string;\n installationId: number;\n}\n\nexport interface ReconcileSweepSummary {\n /** Factory-configured repositories included in the sweep. */\n repositories: number;\n /** PRs whose live state was fetched from GitHub. */\n checked: number;\n /** Missed merges replayed through the rules ingress. */\n merged: number;\n /** Missed closes-without-merge replayed through the rules ingress. */\n closed: number;\n /** PRs/issues (or whole repositories) skipped because of an error. */\n failed: number;\n /** Error samples with context, capped at {@link RECONCILE_ERROR_SAMPLE_LIMIT}. */\n errors: Array<{ repository: string; pullRequestNumber?: number; issueNumber?: number; error: string }>;\n}\n\nexport type GithubPullRequestReconciler = (repositories: ReconcileRepository[]) => Promise<ReconcileSweepSummary>;\n\nexport const RECONCILE_ERROR_SAMPLE_LIMIT = 5;\n\nexport function sameStrings(left: unknown, right: string[] | undefined): boolean {\n if (right === undefined) return true;\n if (!Array.isArray(left)) return false;\n const leftValues = new Set(left.flatMap(value => (typeof value === 'string' ? [value] : [])));\n const rightValues = new Set(right);\n return leftValues.size === rightValues.size && [...leftValues].every(value => rightValues.has(value));\n}\n\n/**\n * Extracts the PR number a work item tracks, but only when the item belongs\n * to the given repository. Card URLs pin the repository unambiguously; the\n * legacy source key embeds the repository id. Canonical keys (`github-pr:N`)\n * carry no repository, so they are only trusted when the item has no URL —\n * a project mapped to multiple repositories must not reconcile one repo's\n * card against another repo's PR number.\n */\nfunction reconcilablePullRequestNumber(item: WorkItemRow, repository: ReconcileRepository): number | undefined {\n if (item.externalSource?.type !== 'pull-request') return undefined;\n const url = item.externalSource.url;\n if (url) {\n const match = /^https?:\\/\\/[^/]+\\/(.+)\\/pull\\/(\\d+)(?:[/?#]|$)/.exec(url);\n if (!match) return undefined;\n return match[1] === repository.fullName ? Number(match[2]) : undefined;\n }\n const externalId = item.externalSource.externalId;\n const legacy = /^github:(\\d+):pull-request:(\\d+)$/.exec(externalId);\n if (legacy) return Number(legacy[1]) === repository.id ? Number(legacy[2]) : undefined;\n const canonical = /^github-pr:(\\d+)$/.exec(externalId);\n return canonical ? Number(canonical[1]) : undefined;\n}\n\n/**\n * Extracts the issue number a work item tracks, but only when the item\n * belongs to the given repository. Stricter than\n * {@link reconcilablePullRequestNumber}: a canonical key with no URL is only\n * trusted when the intake-stamped `githubRepositoryId` confirms the\n * repository, because the sweep initiates closes on its own.\n */\nexport function reconcilableIssueNumber(item: WorkItemRow, repository: ReconcileRepository): number | undefined {\n if (item.externalSource?.type !== 'issue') return undefined;\n const url = item.externalSource.url;\n if (url) {\n const match = /^https?:\\/\\/[^/]+\\/(.+)\\/issues\\/(\\d+)(?:[/?#]|$)/.exec(url);\n if (!match) return undefined;\n // A renamed repository leaves the old owner/name in the card URL, so a\n // URL mismatch still defers to the stable intake-stamped repository id.\n const belongs = match[1] === repository.fullName || item.metadata?.githubRepositoryId === repository.id;\n return belongs ? Number(match[2]) : undefined;\n }\n const externalId = item.externalSource.externalId;\n const legacy = /^github:(\\d+):issue:(\\d+)$/.exec(externalId);\n if (legacy) return Number(legacy[1]) === repository.id ? Number(legacy[2]) : undefined;\n const canonical = /^github-issue:(\\d+)$/.exec(externalId);\n if (!canonical) return undefined;\n // Canonical keys carry no repository; only the intake-stamped repository id\n // can attribute a URL-less card, and guessing would let a multi-repo\n // project close repo B's card because repo A's same-numbered issue closed.\n return item.metadata?.githubRepositoryId === repository.id ? Number(canonical[1]) : undefined;\n}\n\nexport function reconciledIssueClosedEvent(\n repository: ReconcileRepository,\n issueNumber: number,\n state: ReconcileIssueState,\n): ParsedGithubWebhook {\n return {\n event: 'issues',\n // Stable per (repository, issue): the ingress dedupe makes repeat\n // reconcile cycles replay instead of re-committing decisions.\n deliveryId: `reconcile:${repository.id}:issue:${issueNumber}:closed`,\n payload: {\n action: 'closed',\n installation: { id: repository.installationId },\n repository: { id: repository.id, full_name: repository.fullName },\n sender: { login: state.author ?? 'github' },\n issue: {\n number: issueNumber,\n title: state.title,\n html_url: state.url,\n state: 'closed',\n ...(state.stateReason ? { state_reason: state.stateReason } : {}),\n ...(state.createdAt ? { created_at: state.createdAt } : {}),\n ...(state.updatedAt ? { updated_at: state.updatedAt } : {}),\n assignees: githubUsers(state.assignees),\n },\n },\n };\n}\n\n/**\n * The label-drift replay: an open issue whose labels changed without a\n * `labeled`/`unlabeled` webhook ever arriving (Factory was down, the delivery\n * was lost, or the label was applied by something other than a delivery the\n * webhook saw). Synthesized as an `opened` delivery so the deployment's\n * `issueOpened` rule decides placement, exactly as it does at arrival — one\n * source of placement policy for both.\n */\nexport function reconciledIssueRelabeledEvent(\n repository: ReconcileRepository,\n issueNumber: number,\n state: ReconcileIssueState,\n): ParsedGithubWebhook {\n const labels = state.labels ?? [];\n // GitHub updates `updated_at` for a label change. Including it makes retries\n // of one observed issue version idempotent while allowing A → B → A to replay\n // its final A placement as a new version. Synthetic callers without it retain\n // the legacy label-only identity.\n const digest = createHash('sha256')\n .update([...labels].sort().join('\\n'))\n .digest('hex')\n .slice(0, 16);\n const version = state.updatedAt ? `:${createHash('sha256').update(state.updatedAt).digest('hex').slice(0, 16)}` : '';\n return {\n event: 'issues',\n deliveryId: `reconcile:${repository.id}:issue:${issueNumber}:relabeled:${digest}${version}`,\n payload: {\n // `opened` is the event that carries an issue's labels through the rules;\n // an already-filed card is re-placed by the decision, not re-materialized.\n action: 'opened',\n installation: { id: repository.installationId },\n repository: { id: repository.id, full_name: repository.fullName },\n sender: { login: state.author ?? 'github' },\n issue: {\n number: issueNumber,\n title: state.title,\n html_url: state.url,\n state: 'open',\n ...(state.createdAt ? { created_at: state.createdAt } : {}),\n ...(state.updatedAt ? { updated_at: state.updatedAt } : {}),\n assignees: githubUsers(state.assignees),\n labels: githubLabels(labels),\n },\n },\n };\n}\n\n/**\n * The missed-open replay: an open issue with no Work card, because its\n * `opened` delivery never reached the rules ingress. Synthesized as the same\n * `opened` delivery so the deployment's `issueOpened` rule decides whether and\n * where it lands, exactly as it would have at arrival. The delivery id is\n * stable per issue so repeat sweeps dedupe at the ingress.\n */\nexport function reconciledIssueOpenedEvent(\n repository: ReconcileRepository,\n issueNumber: number,\n state: ReconcileIssueState,\n): ParsedGithubWebhook {\n const event = reconciledIssueRelabeledEvent(repository, issueNumber, state);\n return { ...event, deliveryId: `reconcile:${repository.id}:issue:${issueNumber}:opened` };\n}\n\nexport function polledPullRequestEvent(\n repository: ReconcileRepository,\n pullRequestNumber: number,\n state: PolledPullRequestState,\n): ParsedGithubWebhook {\n return {\n event: 'pull_request',\n deliveryId: `poll:${repository.id}:pull-request:${pullRequestNumber}:${state.createdAt}`,\n payload: {\n action: 'opened',\n installation: { id: repository.installationId },\n repository: { id: repository.id, full_name: repository.fullName },\n sender: { login: state.author ?? '__unknown__' },\n pull_request: pullRequestPayload(pullRequestNumber, state),\n },\n };\n}\n\nexport function reconciledClosedEvent(\n repository: ReconcileRepository,\n pullRequestNumber: number,\n state: ReconcilePullRequestState,\n): ParsedGithubWebhook {\n const outcome = state.merged ? 'merged' : 'closed';\n return {\n event: 'pull_request',\n // Stable per (repository, PR, outcome): the ingress dedupe makes repeat\n // reconcile cycles replay instead of re-committing decisions.\n deliveryId: `reconcile:${repository.id}:pull-request:${pullRequestNumber}:${outcome}`,\n payload: {\n action: 'closed',\n installation: { id: repository.installationId },\n repository: { id: repository.id, full_name: repository.fullName },\n sender: { login: state.mergedBy ?? 'github' },\n pull_request: pullRequestPayload(pullRequestNumber, { ...state, state: 'closed' }),\n },\n };\n}\n\nfunction pullRequestPayload(pullRequestNumber: number, state: ReconcilePullRequestState): Record<string, unknown> {\n const payload: Record<string, unknown> = {\n number: pullRequestNumber,\n title: state.title,\n html_url: state.url,\n state: state.state,\n draft: state.draft,\n merged: state.merged,\n assignees: githubUsers(state.assignees),\n requested_reviewers: githubUsers(state.requestedReviewers),\n labels: githubLabels(state.labels),\n head: { ref: state.headBranch },\n base: { ref: state.baseBranch },\n };\n if (state.createdAt) payload.created_at = state.createdAt;\n if (state.author) payload.user = { login: state.author };\n return payload;\n}\n\nfunction githubUsers(logins: readonly string[] = []): Array<{ login: string }> {\n return logins.map(login => ({ login }));\n}\n\nfunction githubLabels(names: readonly string[] = []): Array<{ name: string }> {\n return names.map(name => ({ name }));\n}\n\nfunction reconciledPullRequestMetadata(\n state: ReconcilePullRequestState,\n reconciliation: 'clear' | 'settled',\n authorTrusted?: boolean,\n): Record<string, unknown> {\n return {\n state: state.state,\n draft: state.draft,\n merged: state.merged,\n ...(state.author ? { author: state.author } : {}),\n ...(state.assignees ? { assignees: state.assignees } : {}),\n ...(state.requestedReviewers ? { requestedReviewers: state.requestedReviewers } : {}),\n ...(state.labels ? { labels: state.labels } : {}),\n ...(authorTrusted === undefined ? {} : { authorTrusted }),\n [FACTORY_PULL_REQUEST_RECONCILIATION_KEY]:\n reconciliation === 'settled' ? (state.merged ? 'merged' : 'closed') : null,\n };\n}\n\nfunction reconciledPullRequestOutcome(metadata: Record<string, unknown>): 'merged' | 'closed' | undefined {\n if (metadata.state !== 'closed' || typeof metadata.merged !== 'boolean') return undefined;\n return metadata.merged ? 'merged' : 'closed';\n}\n\n/**\n * The webhook handler retires subscriptions itself; the sweep replays only the\n * rules ingress, so without this the thread's PR chip and the workspace row\n * stay `open` forever on a deployment GitHub cannot reach.\n */\nasync function retireReconciledSubscriptions(\n storage: IntegrationStorageHandle,\n repository: ReconcileRepository,\n pullRequestNumber: number,\n merged: boolean,\n): Promise<void> {\n const target = changeRequestTargetKey({\n installationExternalId: String(repository.installationId),\n repositoryExternalId: String(repository.id),\n changeRequestId: String(pullRequestNumber),\n });\n const rows = await storage.subscriptions.listByTarget(target);\n await Promise.all(\n rows\n .filter(row => row.status === 'open')\n .map(row => storage.subscriptions.updateStatus(row.id, merged ? 'merged' : 'closed')),\n );\n}\n\n/**\n * State-based safety net for merge signals: webhooks and event-log tailing\n * can miss a merge (cursor gaps, downtime, terminally failed decisions), so\n * this sweep compares still-open PR cards against actual GitHub state and\n * replays the merge through the normal rules ingress when they disagree.\n */\nexport function createGithubPullRequestReconciler(\n options: GithubRulesOptions,\n fetchPullRequest: GithubPullRequestFetcher,\n): GithubPullRequestReconciler {\n const rules = new GithubRules(options);\n return async repositories => {\n const summary: ReconcileSweepSummary = {\n repositories: 0,\n checked: 0,\n merged: 0,\n closed: 0,\n failed: 0,\n errors: [],\n };\n const recordFailure = (repository: ReconcileRepository, error: unknown, pullRequestNumber?: number) => {\n summary.failed += 1;\n if (summary.errors.length < RECONCILE_ERROR_SAMPLE_LIMIT) {\n summary.errors.push({\n repository: repository.fullName,\n ...(pullRequestNumber === undefined ? {} : { pullRequestNumber }),\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n // An installation can expose hundreds of repositories; only the ones\n // actually linked to a factory project can have cards to reconcile, so\n // scope the sweep to those up front instead of probing each repository.\n const configured = new Set(\n (await options.sourceControl.projectRepositories.listConfiguredExternalKeys()).map(\n key => `${key.installationExternalId}\\u0000${key.repositoryExternalId}`,\n ),\n );\n const scoped = repositories.filter(repository =>\n configured.has(`${repository.installationId}\\u0000${repository.id}`),\n );\n summary.repositories = scoped.length;\n for (const repository of scoped) {\n // One broken repository (or a failing token exchange for its\n // installation) must not abort the sweep for the others.\n let cardsByNumber: Map<number, WorkItemRow[]>;\n let unanswered: Array<{ item: WorkItemRow; author: string }>;\n try {\n const projects = await options.sourceControl.projectRepositories.listByExternalRepository({\n installationExternalId: String(repository.installationId),\n repositoryExternalId: String(repository.id),\n });\n if (projects.length === 0) continue;\n cardsByNumber = new Map<number, WorkItemRow[]>();\n unanswered = [];\n for (const project of projects) {\n const items = await options.storage.list({\n orgId: project.orgId,\n factoryProjectId: project.factoryProjectId,\n });\n for (const item of items) {\n const unansweredAuthor = authorAwaitingTrust(item, repository);\n if (unansweredAuthor) unanswered.push({ item, author: unansweredAuthor });\n const pullRequestNumber = reconcilablePullRequestNumber(item, repository);\n if (!pullRequestNumber) continue;\n const metadata = item.metadata ?? {};\n const reconciliation = metadata[FACTORY_PULL_REQUEST_RECONCILIATION_KEY];\n const reconciledOutcome = reconciledPullRequestOutcome(metadata);\n if (\n workItemPhaseSemantics(options.boards, item)?.kind === 'terminal' &&\n reconciledOutcome !== undefined &&\n reconciliation === reconciledOutcome\n ) {\n continue;\n }\n const cards = cardsByNumber.get(pullRequestNumber) ?? [];\n cards.push(item);\n cardsByNumber.set(pullRequestNumber, cards);\n }\n }\n } catch (error) {\n recordFailure(repository, error);\n continue;\n }\n const authorTrust = sweepTrustLookup(options.github, repository);\n for (const { item, author } of unanswered) {\n try {\n await options.storage.update({\n orgId: item.orgId,\n id: item.id,\n userId: 'factory-rule-dispatcher',\n patch: { metadata: { authorTrusted: await authorTrust(author) } },\n });\n } catch (error) {\n recordFailure(repository, error);\n }\n }\n for (const [pullRequestNumber, cards] of cardsByNumber) {\n try {\n const state = await fetchPullRequest({\n installationId: repository.installationId,\n repository: repository.fullName,\n number: pullRequestNumber,\n });\n summary.checked += 1;\n if (!state) continue;\n // Re-stamped on every sweep so revoked write access reads untrusted\n // within one cycle; a failed lookup keeps the last stamp and retries.\n let authorTrusted: boolean | undefined;\n if (state.author !== undefined) {\n try {\n authorTrusted = await authorTrust(state.author);\n } catch (error) {\n recordFailure(repository, error, pullRequestNumber);\n }\n }\n for (const card of cards) {\n if (state.state === 'closed') continue;\n const metadata = card.metadata ?? {};\n const statusChanged =\n metadata.state !== state.state || metadata.draft !== state.draft || metadata.merged !== state.merged;\n const authorChanged = state.author !== undefined && metadata.author !== state.author;\n const assigneesChanged = !sameStrings(metadata.assignees, state.assignees);\n const reviewersChanged = !sameStrings(metadata.requestedReviewers, state.requestedReviewers);\n const labelsChanged = !sameStrings(metadata.labels, state.labels);\n const trustStale = authorTrusted !== undefined && metadata.authorTrusted !== authorTrusted;\n const metadataChanged =\n statusChanged || authorChanged || assigneesChanged || reviewersChanged || labelsChanged || trustStale;\n const reconciliation = metadata[FACTORY_PULL_REQUEST_RECONCILIATION_KEY];\n if (!metadataChanged && reconciliation !== 'merged' && reconciliation !== 'closed') continue;\n try {\n await options.storage.update({\n orgId: card.orgId,\n id: card.id,\n userId: 'factory-rule-dispatcher',\n patch: {\n metadata: reconciledPullRequestMetadata(state, 'clear', trustStale ? authorTrusted : undefined),\n },\n });\n } catch (error) {\n recordFailure(repository, error, pullRequestNumber);\n }\n }\n if (state.state !== 'closed') continue;\n const cleanupFailures = new Set<string>();\n for (const card of cards) {\n if (workItemPhaseSemantics(options.boards, card)?.kind !== 'terminal') continue;\n try {\n await options.storage.supersedeDecisionsForWorkItem({\n orgId: card.orgId,\n factoryProjectId: card.factoryProjectId,\n workItemId: card.id,\n supersededAt: new Date(),\n });\n } catch (error) {\n recordFailure(repository, error, pullRequestNumber);\n cleanupFailures.add(card.id);\n }\n }\n await rules.ingest(reconciledClosedEvent(repository, pullRequestNumber, state));\n await retireReconciledSubscriptions(options.integrationStorage, repository, pullRequestNumber, state.merged);\n for (const card of cards) {\n if (cleanupFailures.has(card.id)) continue;\n const trustStale = authorTrusted !== undefined && (card.metadata ?? {}).authorTrusted !== authorTrusted;\n try {\n await options.storage.update({\n orgId: card.orgId,\n id: card.id,\n userId: 'factory-rule-dispatcher',\n patch: {\n metadata: reconciledPullRequestMetadata(state, 'settled', trustStale ? authorTrusted : undefined),\n },\n });\n } catch (error) {\n recordFailure(repository, error, pullRequestNumber);\n }\n }\n if (state.merged) summary.merged += 1;\n else summary.closed += 1;\n } catch (error) {\n recordFailure(repository, error, pullRequestNumber);\n }\n }\n }\n return summary;\n };\n}\n\nexport function githubRulesOptions(\n github: GithubRulesIntegration,\n context: IntegrationContext,\n): GithubRulesOptions | undefined {\n if (!context.runtime) return undefined;\n return {\n github,\n sourceControl: context.storage.sourceControl,\n integrationStorage: context.storage.generic,\n projects: context.storage.projects,\n storage: context.runtime.workItems,\n configVersion: context.runtime.configVersion,\n boards: context.runtime.boards,\n intake: context.storage.intake,\n ...(context.hooks?.onRepositoryPush ? { onRepositoryPush: context.hooks.onRepositoryPush } : {}),\n };\n}\n\nexport function attachGithubRules(\n github: GithubRulesIntegration,\n context: IntegrationContext,\n): ((event: ParsedGithubWebhook) => Promise<unknown>) | undefined {\n const options = githubRulesOptions(github, context);\n if (!options) return undefined;\n const rules = new GithubRules(options);\n return event => rules.ingest(event);\n}\n\nexport function attachGithubReconciler(\n github: GithubRulesIntegration,\n context: IntegrationContext,\n fetchPullRequest: GithubPullRequestFetcher,\n): GithubPullRequestReconciler | undefined {\n const options = githubRulesOptions(github, context);\n if (!options) return undefined;\n return createGithubPullRequestReconciler(options, fetchPullRequest);\n}\n"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Stop or destroy the sandbox a session holds in this process, dropping it
3
+ * from the per-process memo first so later opens construct fresh.
4
+ *
5
+ * Sandbox identity is the session id, so there is no reuse pool to publish
6
+ * into — a reopened session resolves the same id through its provider
7
+ * (reconnect/resume, or a fresh VM whose setup hook re-materializes).
8
+ * Sessions never opened in this replica have no memo entry; their VMs are
9
+ * left to the provider's idle lifecycle (pause / idle GC).
10
+ */
11
+ export declare function releaseSessionSandbox(options: {
12
+ /** The session's storage row id (the sandbox identity). */
13
+ sessionId: string;
14
+ /** Destroy instead of stop — for sessions that are gone for good. */
15
+ destroy?: boolean;
16
+ }): Promise<void>;
17
+ /**
18
+ * Tear down the sandbox a just-deleted user session was holding. The row is
19
+ * already gone, so the VM is destroyed rather than stopped — nothing will
20
+ * ever resolve this session id again.
21
+ */
22
+ export declare function reclaimDeletedSessionSandbox(options: {
23
+ session: Pick<import('../../storage/domains/source-control/base.js').SourceControlSession, 'id'>;
24
+ }): Promise<void>;
25
+ //# sourceMappingURL=sandbox-release.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-release.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/sandbox-release.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAehB;AAED;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,OAAO,EAAE,IAAI,CAAC,OAAO,8CAA8C,EAAE,oBAAoB,EAAE,IAAI,CAAC,CAAC;CAClG,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhB"}
@@ -0,0 +1,38 @@
1
+ import { evictSessionSandbox, peekSessionSandbox } from "../../sandbox/session-sandbox.js";
2
+ //#region src/integrations/github/sandbox-release.ts
3
+ /**
4
+ * Stop or destroy the sandbox a session holds in this process, dropping it
5
+ * from the per-process memo first so later opens construct fresh.
6
+ *
7
+ * Sandbox identity is the session id, so there is no reuse pool to publish
8
+ * into — a reopened session resolves the same id through its provider
9
+ * (reconnect/resume, or a fresh VM whose setup hook re-materializes).
10
+ * Sessions never opened in this replica have no memo entry; their VMs are
11
+ * left to the provider's idle lifecycle (pause / idle GC).
12
+ */
13
+ async function releaseSessionSandbox(options) {
14
+ const entry = peekSessionSandbox(options.sessionId);
15
+ if (!entry) return;
16
+ evictSessionSandbox(options.sessionId);
17
+ const sandbox = entry.sandbox;
18
+ if (options.destroy) {
19
+ await (sandbox._destroy ? sandbox._destroy() : sandbox.destroy?.());
20
+ return;
21
+ }
22
+ await (sandbox._stop ? sandbox._stop() : sandbox.stop?.());
23
+ }
24
+ /**
25
+ * Tear down the sandbox a just-deleted user session was holding. The row is
26
+ * already gone, so the VM is destroyed rather than stopped — nothing will
27
+ * ever resolve this session id again.
28
+ */
29
+ async function reclaimDeletedSessionSandbox(options) {
30
+ await releaseSessionSandbox({
31
+ sessionId: options.session.id,
32
+ destroy: true
33
+ });
34
+ }
35
+ //#endregion
36
+ export { reclaimDeletedSessionSandbox, releaseSessionSandbox };
37
+
38
+ //# sourceMappingURL=sandbox-release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-release.js","names":[],"sources":["../../../src/integrations/github/sandbox-release.ts"],"sourcesContent":["import { evictSessionSandbox, peekSessionSandbox } from '../../sandbox/session-sandbox.js';\n\n/**\n * Stop or destroy the sandbox a session holds in this process, dropping it\n * from the per-process memo first so later opens construct fresh.\n *\n * Sandbox identity is the session id, so there is no reuse pool to publish\n * into — a reopened session resolves the same id through its provider\n * (reconnect/resume, or a fresh VM whose setup hook re-materializes).\n * Sessions never opened in this replica have no memo entry; their VMs are\n * left to the provider's idle lifecycle (pause / idle GC).\n */\nexport async function releaseSessionSandbox(options: {\n /** The session's storage row id (the sandbox identity). */\n sessionId: string;\n /** Destroy instead of stop — for sessions that are gone for good. */\n destroy?: boolean;\n}): Promise<void> {\n const entry = peekSessionSandbox(options.sessionId);\n if (!entry) return;\n evictSessionSandbox(options.sessionId);\n const sandbox = entry.sandbox as unknown as {\n _stop?: () => Promise<void>;\n _destroy?: () => Promise<void>;\n stop?: () => Promise<void>;\n destroy?: () => Promise<void>;\n };\n if (options.destroy) {\n await (sandbox._destroy ? sandbox._destroy() : sandbox.destroy?.());\n return;\n }\n await (sandbox._stop ? sandbox._stop() : sandbox.stop?.());\n}\n\n/**\n * Tear down the sandbox a just-deleted user session was holding. The row is\n * already gone, so the VM is destroyed rather than stopped — nothing will\n * ever resolve this session id again.\n */\nexport async function reclaimDeletedSessionSandbox(options: {\n session: Pick<import('../../storage/domains/source-control/base.js').SourceControlSession, 'id'>;\n}): Promise<void> {\n await releaseSessionSandbox({ sessionId: options.session.id, destroy: true });\n}\n"],"mappings":";;;;;;;;;;;;AAYA,eAAsB,sBAAsB,SAK1B;CAChB,MAAM,QAAQ,mBAAmB,QAAQ,SAAS;CAClD,IAAI,CAAC,OAAO;CACZ,oBAAoB,QAAQ,SAAS;CACrC,MAAM,UAAU,MAAM;CAMtB,IAAI,QAAQ,SAAS;EACnB,OAAO,QAAQ,WAAW,QAAQ,SAAS,IAAI,QAAQ,UAAU;EACjE;CACF;CACA,OAAO,QAAQ,QAAQ,QAAQ,MAAM,IAAI,QAAQ,OAAO;AAC1D;;;;;;AAOA,eAAsB,6BAA6B,SAEjC;CAChB,MAAM,sBAAsB;EAAE,WAAW,QAAQ,QAAQ;EAAI,SAAS;CAAK,CAAC;AAC9E"}
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Repo materialization for GitHub-backed repositories.
3
+ *
4
+ * A GitHub repo is never cloned onto the server host. The repo is cloned
5
+ * *inside* the session's sandbox, so the agent's file tools and command tools
6
+ * operate entirely against the remote checkout.
7
+ *
8
+ * - `materializeRepo(row, token)` clones the repo inside the sandbox when no
9
+ * checkout exists yet (a base-image boot, a wiped disk), supplying the
10
+ * short-lived token only in that Git process's environment. A checkout that
11
+ * is already there, from a repo template image or an earlier start, is left
12
+ * exactly as it is.
13
+ *
14
+ * This module owns everything git/GitHub: clone, commit/push, setup/teardown commands,
15
+ * and `gh pr create`. Workdir layout lives in `../sandbox/workdir`.
16
+ */
17
+ import type { RepositoryAccess } from '../../capabilities/version-control.js';
18
+ import { isValidGitRef } from '../../sandbox/git-ref.js';
19
+ import type { ExecutableSandbox, SandboxCommandResult } from '../../sandbox/materialization.js';
20
+ import type { SourceControlStorageHandle } from '../../storage/domains/source-control/base.js';
21
+ type MaterializationStore = Pick<SourceControlStorageHandle['sessions'], 'markMaterialized'>;
22
+ interface RepoMaterializationBinding {
23
+ id: string;
24
+ sandboxWorkdir: string;
25
+ materializedAt: Date | null;
26
+ }
27
+ /**
28
+ * Single-quote a string for safe POSIX shell interpolation. Wraps the value in
29
+ * single quotes and escapes any embedded single quote using the canonical
30
+ * close-quote / escaped-quote / reopen-quote sequence (`'\''`). This is the
31
+ * standard POSIX-safe construction and prevents the quoted string from being
32
+ * terminated early.
33
+ */
34
+ export declare function shellQuote(value: string): string;
35
+ /**
36
+ * Default hang guard for sandbox shell commands. Generous by design — large
37
+ * clones and dependency installs legitimately take minutes; the guard exists
38
+ * so a wedged sandbox surfaces a failure instead of hanging the request that
39
+ * triggered materialization forever.
40
+ */
41
+ export declare const DEFAULT_COMMAND_TIMEOUT_MS: number;
42
+ /** Branch checkout only fetches one ref — a much tighter budget applies. */
43
+ export declare const CHECKOUT_COMMAND_TIMEOUT_MS: number;
44
+ interface ShOptions {
45
+ /** Override the hang-guard budget for this command. */
46
+ timeoutMs?: number;
47
+ /** Human-readable phase name included in the timeout error. */
48
+ phase?: string;
49
+ }
50
+ /**
51
+ * Run a shell script in the sandbox via `sh -c`. This is reserved for the
52
+ * explicitly configured repository lifecycle hooks; programmatic commands use
53
+ * {@link execute} with an argv array.
54
+ */
55
+ export declare function sh(sandbox: ExecutableSandbox, script: string, options?: ShOptions): Promise<SandboxCommandResult>;
56
+ /** Error raised when the sandbox cannot materialize the repo (actionable). */
57
+ export declare class MaterializeError extends Error {
58
+ readonly code: 'git-missing' | 'egress-blocked' | 'clone-failed' | 'pull-failed' | 'push-failed' | 'commit-failed' | 'gh-missing' | 'pr-failed';
59
+ constructor(message: string, code: 'git-missing' | 'egress-blocked' | 'clone-failed' | 'pull-failed' | 'push-failed' | 'commit-failed' | 'gh-missing' | 'pr-failed');
60
+ }
61
+ /** Repo metadata needed to materialize, read from the org-owned project row. */
62
+ export interface RepoMaterializeInfo {
63
+ repoFullName: string;
64
+ defaultBranch: string;
65
+ /** Provider-supplied, credential-free HTTPS clone URL. */
66
+ cloneUrl?: string;
67
+ /** Username paired with the bearer token for git-over-HTTPS. */
68
+ authUsername?: string;
69
+ }
70
+ /** Options for {@link materializeRepo}. */
71
+ export interface MaterializeRepoOptions {
72
+ /** The per-(project,user) sandbox binding whose workdir this materializes into. */
73
+ row: RepoMaterializationBinding;
74
+ /** Repo metadata from the org-owned project row. */
75
+ repoInfo: RepoMaterializeInfo;
76
+ /** The live sandbox to run git inside. */
77
+ sandbox: ExecutableSandbox;
78
+ /** A freshly minted, short-lived installation access token. */
79
+ token: string;
80
+ storage: MaterializationStore;
81
+ }
82
+ /**
83
+ * Materialize the repo inside the user's sandbox: clone when no checkout of
84
+ * this repo exists, otherwise nothing. Credentials are process-scoped and the
85
+ * stored remote remains credential-free. Sets `materialized_at` on the
86
+ * per-user sandbox binding row.
87
+ */
88
+ export declare function materializeRepo(options: MaterializeRepoOptions): Promise<void>;
89
+ export interface SessionBranchOptions {
90
+ branch: string;
91
+ baseBranch: string;
92
+ token: string;
93
+ repoFullName: string;
94
+ cloneUrl?: string;
95
+ authUsername?: string;
96
+ /** A pull-request card's session starts on the PR head instead of the base tip. */
97
+ pullRequestNumber?: number;
98
+ /** A GitLab merge-request card's session starts on the MR head instead of the base tip. */
99
+ mergeRequestNumber?: number;
100
+ }
101
+ /** Check out a session's branch inside its isolated repository clone. */
102
+ export declare function checkoutSessionBranch(sandbox: ExecutableSandbox, workdir: string, options: SessionBranchOptions): Promise<void>;
103
+ export interface SyncEnvironmentRepositoryOptions {
104
+ /** The session branch to resume when the remote already carries it. */
105
+ branch: string;
106
+ /** The repository's default branch; new session branches start at its remote tip. */
107
+ defaultBranch: string;
108
+ token: string;
109
+ repoFullName: string;
110
+ cloneUrl?: string;
111
+ authUsername?: string;
112
+ }
113
+ export interface EnvironmentSyncResult {
114
+ outcome: 'resumed' | 'created' | 'kept';
115
+ /** The branch the checkout ends on; `null` when it stays detached. */
116
+ branch: string | null;
117
+ }
118
+ /**
119
+ * Bring a secondary environment repository onto the session branch at
120
+ * session start. The primary repository keeps {@link checkoutSessionBranch};
121
+ * every other repository follows a conservative rule: resume the session
122
+ * branch when the remote or the local clone has it, otherwise create it from
123
+ * the default branch tip (a detached HEAD, the template image pinned at its
124
+ * build commit, is moved there first). A checkout that sits on any other
125
+ * branch is left alone: it may carry local-only commits.
126
+ */
127
+ export declare function syncEnvironmentRepository(sandbox: ExecutableSandbox, workdir: string, options: SyncEnvironmentRepositoryOptions): Promise<EnvironmentSyncResult>;
128
+ /** Refresh an existing GitLab review checkout without exposing its credential to the agent. */
129
+ export declare function refreshMergeRequestCheckout(sandbox: ExecutableSandbox, workdir: string, input: {
130
+ branch: string;
131
+ mergeRequestNumber: number;
132
+ expectedHeadSha: string;
133
+ access: RepositoryAccess;
134
+ }): Promise<{
135
+ headSha: string;
136
+ changed: boolean;
137
+ }>;
138
+ export { isValidGitRef };
139
+ /** Identity used to author commits inside the sandbox. */
140
+ export interface GitIdentity {
141
+ name?: string | null;
142
+ email?: string | null;
143
+ /** GitHub login, used to derive a stable noreply identity when name/email are absent. */
144
+ login?: string | null;
145
+ }
146
+ /**
147
+ * Resolve a concrete `{ name, email }` for git authorship from a possibly-sparse
148
+ * identity. Falls back to a GitHub-style noreply identity so commits are never
149
+ * authored with an empty or host-derived identity.
150
+ */
151
+ export declare function resolveGitIdentity(identity: GitIdentity): {
152
+ name: string;
153
+ email: string;
154
+ };
155
+ /** Configure repository-local commit identity through direct Git argv calls. */
156
+ export declare function configureGitIdentity(sandbox: ExecutableSandbox, workdir: string, identity: GitIdentity): Promise<void>;
157
+ /** Whether the checkout has a local `refs/heads/<branch>`. */
158
+ export declare function hasLocalBranch(sandbox: ExecutableSandbox, workdir: string, branch: string): Promise<boolean>;
159
+ /**
160
+ * Make sure the checkout has a local `<branch>`. Where it was never created,
161
+ * create it at `HEAD` and switch to it, so the agent's next commits land on
162
+ * the branch every push sends; the index and working tree carry over.
163
+ */
164
+ export declare function ensureLocalBranch(sandbox: ExecutableSandbox, workdir: string, branch: string): Promise<void>;
165
+ /** Whether `workdir` is a checkout of the repository at `cloneUrl`. */
166
+ export declare function isCheckoutOf(sandbox: ExecutableSandbox, workdir: string, cloneUrl: string): Promise<boolean>;
167
+ /**
168
+ * Push a branch back to GitHub with credentials scoped to the Git process.
169
+ * The token never enters argv, a repository URL, or persistent configuration.
170
+ */
171
+ export declare function pushBranch(sandbox: ExecutableSandbox, workdir: string, branch: string, token: string, repoFullName: string): Promise<void>;
172
+ /**
173
+ * Push the active session branch through the provider-neutral repository
174
+ * access contract without persisting or exposing provider credentials.
175
+ */
176
+ export declare function pushRepositoryBranch(sandbox: ExecutableSandbox, workdir: string, branch: string, access: RepositoryAccess, repoFullName: string): Promise<void>;
177
+ export interface CommitResult {
178
+ /** True when a commit was created; false when there was nothing to commit. */
179
+ committed: boolean;
180
+ }
181
+ /**
182
+ * Stage every change in the working tree and create a commit inside the
183
+ * sandbox. The git identity is configured first so authorship is correct. When
184
+ * there is nothing to commit this is a no-op (`committed: false`) rather than an
185
+ * error, so callers can safely commit-then-push without first diffing.
186
+ *
187
+ * @param sandbox the live sandbox containing the checkout
188
+ * @param workdir the session workdir to commit in
189
+ * @param message the commit message (passed as one argv value)
190
+ * @param identity authorship identity for the commit
191
+ */
192
+ export declare function commitAll(sandbox: ExecutableSandbox, workdir: string, message: string, identity: GitIdentity): Promise<CommitResult>;
193
+ /** Error raised when the org's setup or teardown command fails in the sandbox. */
194
+ export declare class SetupCommandError extends Error {
195
+ readonly code: 'setup-failed' | 'teardown-failed';
196
+ constructor(message: string, code: 'setup-failed' | 'teardown-failed');
197
+ }
198
+ export declare function runSetupCommand(sandbox: ExecutableSandbox, workdir: string, command: string): Promise<void>;
199
+ /**
200
+ * Run the repository's best-effort teardown command from the materialized
201
+ * session workdir. Callers own lifecycle policy: this helper reports failures
202
+ * so the retirement coordinator can log them while still continuing with
203
+ * scrub, pooling/destruction, cache invalidation, and row deletion.
204
+ */
205
+ export declare function runTeardownCommand(sandbox: ExecutableSandbox, workdir: string, command: string, options?: {
206
+ timeoutMs?: number;
207
+ }): Promise<void>;
208
+ export interface CreatePullRequestArgs {
209
+ /** Short-lived installation token, injected only into the `gh` process env. */
210
+ token: string;
211
+ /** Base branch the PR merges into. Ref-validated. */
212
+ base: string;
213
+ /** Head branch the PR is opened from. Ref-validated. */
214
+ head: string;
215
+ /** PR title. */
216
+ title: string;
217
+ /** PR body (optional). */
218
+ body?: string;
219
+ }
220
+ export interface CreatePullRequestResult {
221
+ /** The PR URL parsed from `gh pr create` stdout. */
222
+ url: string;
223
+ }
224
+ /**
225
+ * Open a pull request from inside the sandbox via `gh pr create`. The token is
226
+ * passed only through a per-invocation `GH_TOKEN` env scoped to the single `gh`
227
+ * process (never persisted), all arguments are passed as structured argv, and
228
+ * the resulting PR URL is parsed from stdout.
229
+ *
230
+ * @param sandbox live sandbox containing the checkout
231
+ * @param workdir the worktree (or repo) path the PR head branch is checked out in
232
+ */
233
+ export declare function createPullRequest(sandbox: ExecutableSandbox, workdir: string, { token, base, head, title, body }: CreatePullRequestArgs): Promise<CreatePullRequestResult>;
234
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/integrations/github/sandbox.ts"],"names":[],"mappings":"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"}