@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,1375 @@
1
+ import { attachGithubReconciler, attachGithubRules } from "./rules.js";
2
+ import { createGithubSubscriptionTools, parseCreatedPullRequest, subscribeCurrentSessionToPullRequest } from "./session-subscriptions.js";
3
+ import { resolveGithubRules } from "./default-rules.js";
4
+ import { attachGithubIssueReconciler } from "./issue-reconciler.js";
5
+ import { reconcileInterval, reconciliationEnabled } from "./reconciliation-config.js";
6
+ import { buildGithubRoutes, ingestLinkedRepositoryBacklog } from "./routes.js";
7
+ import { settleOrAbort } from "./settle-or-abort.js";
8
+ import { GithubReconcileWorker } from "./reconcile-worker.js";
9
+ import { Octokit } from "@octokit/rest";
10
+ import { createAppAuth } from "@octokit/auth-app";
11
+ //#region src/integrations/github/integration.ts
12
+ /**
13
+ * Normalize a PEM private key supplied via env. Env tooling tends to mangle
14
+ * multi-line PEMs, so two single-line forms are supported:
15
+ * - `\n`-escaped: literal `\n` sequences become real newlines
16
+ * - fully flattened: newlines stripped entirely — the PEM is rebuilt by
17
+ * re-wrapping the base64 body (Node's decoder rejects header/body/footer
18
+ * on one line with `error:1E08010C:DECODER routines::unsupported`)
19
+ */
20
+ function normalizePrivateKey(raw) {
21
+ const key = raw.replace(/\\n/g, "\n");
22
+ if (key.includes("\n")) return key;
23
+ const flattened = key.trim().match(/^(-----BEGIN [A-Z0-9 ]+-----)\s*(.+?)\s*(-----END [A-Z0-9 ]+-----)$/);
24
+ if (!flattened) return key;
25
+ const body = flattened[2].replace(/\s+/g, "");
26
+ return `${flattened[1]}\n${body.match(/.{1,64}/g).join("\n")}\n${flattened[3]}\n`;
27
+ }
28
+ /**
29
+ * How long a collaborator permission lookup may be reused. The reconcile
30
+ * sweep re-stamps every open card's author and webhook gating checks every
31
+ * human sender, so one login can cost dozens of identical requests per cycle
32
+ * against the installation's REST budget. Revoked access reads as trusted for
33
+ * at most this long.
34
+ */
35
+ const COLLABORATOR_PERMISSION_CACHE_TTL_MS = 30 * 6e4;
36
+ const COLLABORATOR_PERMISSION_CACHE_MAX_ENTRIES = 1e3;
37
+ /** Bound on the shared upstream lookup; callers race their own signal against it. */
38
+ const COLLABORATOR_PERMISSION_LOOKUP_TIMEOUT_MS = 1e4;
39
+ /** Installations whose Octokit (and cached token) is kept; least recently used is evicted. */
40
+ const INSTALLATION_OCTOKIT_CACHE_MAX_ENTRIES = 1e3;
41
+ /** Missed-open issue discovery reads at most this many pages per repository per sweep. */
42
+ const OPEN_ISSUE_DISCOVERY_MAX_PAGES = 5;
43
+ const OPEN_ISSUE_DISCOVERY_PAGE_SIZE = 100;
44
+ /** Page size for issue/PR listings; one GitHub API call per page. */
45
+ const LIST_PAGE_SIZE = 30;
46
+ /** Allow GitHub OAuth token exchanges enough time to complete during installation callbacks. */
47
+ const GITHUB_OAUTH_TOKEN_TIMEOUT_MS = 1e4;
48
+ /** Human-readable names of the required config fields, for construction errors. */
49
+ const REQUIRED_FIELDS = [
50
+ "appId",
51
+ "privateKey",
52
+ "clientId",
53
+ "clientSecret",
54
+ "slug"
55
+ ];
56
+ var GithubIntegration = class {
57
+ /** Stable integration identifier (see `../factory-integration.ts`). */
58
+ id = "github";
59
+ #rules;
60
+ get rules() {
61
+ return this.#rules;
62
+ }
63
+ intake = {
64
+ resolveIntakeDispatch: (input) => this.#resolveIntakeDispatch(input),
65
+ listSources: async ({ orgId }) => {
66
+ const installations = await this.sourceControlStorage.installations.list({ orgId });
67
+ return (await Promise.all(installations.map((installation) => this.sourceControlStorage.repositories.list({
68
+ orgId,
69
+ installationId: installation.id
70
+ })))).flat().map((repository) => ({
71
+ id: repository.id,
72
+ name: repository.slug,
73
+ type: "repository",
74
+ metadata: { defaultBranch: repository.defaultBranch }
75
+ }));
76
+ },
77
+ listItems: async ({ orgId, sourceIds, cursor }) => {
78
+ const page = cursor ? Number.parseInt(cursor, 10) : 1;
79
+ const requestedPage = Number.isSafeInteger(page) && page > 0 ? page : 1;
80
+ const pages = await Promise.all(sourceIds.map(async (sourceId) => {
81
+ const repository = await this.sourceControlStorage.repositories.get({
82
+ orgId,
83
+ id: sourceId
84
+ });
85
+ if (!repository) return {
86
+ items: [],
87
+ hasNextPage: false
88
+ };
89
+ const installation = await this.sourceControlStorage.installations.get({
90
+ orgId,
91
+ id: repository.installationId
92
+ });
93
+ if (!installation) return {
94
+ items: [],
95
+ hasNextPage: false
96
+ };
97
+ const installationId = Number.parseInt(installation.externalId, 10);
98
+ if (!Number.isSafeInteger(installationId)) return {
99
+ items: [],
100
+ hasNextPage: false
101
+ };
102
+ const [issues, pullRequests] = await Promise.all([this.listRepoOpenIssues(installationId, repository.slug, requestedPage), this.versionControl.listPullRequests({
103
+ connection: {
104
+ type: "app-installation",
105
+ installationId
106
+ },
107
+ sourceId: repository.slug,
108
+ includeDrafts: false,
109
+ cursor: String(requestedPage)
110
+ })]);
111
+ return {
112
+ items: [...issues.issues.map((issue) => ({
113
+ source: {
114
+ type: "issue",
115
+ externalId: `${repository.externalId}:${issue.number}`,
116
+ url: issue.url
117
+ },
118
+ sourceId: repository.id,
119
+ title: issue.title,
120
+ status: "open",
121
+ labels: issue.labels,
122
+ createdAt: issue.createdAt,
123
+ updatedAt: issue.updatedAt,
124
+ metadata: {
125
+ repository: repository.slug,
126
+ number: issue.number,
127
+ author: issue.author
128
+ }
129
+ })), ...pullRequests.pullRequests.map((pullRequest) => ({
130
+ source: {
131
+ type: "pull-request",
132
+ externalId: `${repository.externalId}:${pullRequest.id}`,
133
+ url: pullRequest.url
134
+ },
135
+ sourceId: repository.id,
136
+ title: pullRequest.title,
137
+ status: "open",
138
+ createdAt: pullRequest.createdAt,
139
+ updatedAt: pullRequest.updatedAt,
140
+ metadata: {
141
+ repository: repository.slug,
142
+ number: Number(pullRequest.id),
143
+ author: pullRequest.author,
144
+ baseBranch: pullRequest.baseBranch,
145
+ headBranch: pullRequest.headBranch
146
+ }
147
+ }))],
148
+ hasNextPage: issues.nextPage !== null || pullRequests.nextCursor !== null
149
+ };
150
+ }));
151
+ return {
152
+ items: pages.flatMap((result) => result.items),
153
+ nextCursor: pages.some((result) => result.hasNextPage) ? String(requestedPage + 1) : null
154
+ };
155
+ },
156
+ listIssues: (input) => this.#listIntakeIssues(input),
157
+ getIssue: (input) => this.#getIntakeIssue(input),
158
+ createComment: (input) => this.#createIntakeComment(input),
159
+ updateIssue: (input) => this.#updateIntakeIssue(input)
160
+ };
161
+ versionControl = {
162
+ initialize: ({ storage }) => {
163
+ this.#sourceControlStorage = storage;
164
+ },
165
+ registerInstallation: ({ orgId, userId, installation }) => this.sourceControlStorage.installations.upsert({
166
+ orgId,
167
+ connectedByUserId: userId,
168
+ externalId: installation.externalId,
169
+ accountName: installation.accountName,
170
+ accountType: installation.accountType,
171
+ providerMetadata: installation.metadata
172
+ }),
173
+ registerRepositories: ({ orgId, installationId, repositories }) => Promise.all(repositories.map((repository) => this.sourceControlStorage.repositories.upsert({
174
+ orgId,
175
+ input: {
176
+ installationId,
177
+ externalId: repository.externalId,
178
+ slug: repository.slug,
179
+ defaultBranch: repository.defaultBranch,
180
+ providerMetadata: repository.metadata
181
+ }
182
+ }))),
183
+ getRepositoryTarget: async ({ orgId, repositoryId }) => {
184
+ const repository = await this.sourceControlStorage.repositories.get({
185
+ orgId,
186
+ id: repositoryId
187
+ });
188
+ if (!repository) throw new Error("Version-control repository not found.");
189
+ const installation = await this.sourceControlStorage.installations.get({
190
+ orgId,
191
+ id: repository.installationId
192
+ });
193
+ if (!installation) throw new Error("Version-control installation not found.");
194
+ const installationId = Number.parseInt(installation.externalId, 10);
195
+ if (!Number.isSafeInteger(installationId)) throw new Error("GitHub installation id is invalid.");
196
+ return {
197
+ connection: {
198
+ type: "app-installation",
199
+ installationId
200
+ },
201
+ sourceId: repository.slug
202
+ };
203
+ },
204
+ getRepositoryAccess: async ({ orgId, repositoryId }) => {
205
+ const repository = await this.sourceControlStorage.repositories.get({
206
+ orgId,
207
+ id: repositoryId
208
+ });
209
+ if (!repository) throw new Error("Version-control repository not found.");
210
+ const installation = await this.sourceControlStorage.installations.get({
211
+ orgId,
212
+ id: repository.installationId
213
+ });
214
+ if (!installation) throw new Error("Version-control installation not found.");
215
+ const installationId = Number.parseInt(installation.externalId, 10);
216
+ if (!Number.isSafeInteger(installationId)) throw new Error("GitHub installation id is invalid.");
217
+ return {
218
+ cloneUrl: `https://github.com/${repository.slug}.git`,
219
+ authorization: {
220
+ scheme: "bearer",
221
+ token: await this.mintInstallationToken(installationId)
222
+ }
223
+ };
224
+ },
225
+ listPullRequests: (input) => this.#listPullRequests(input),
226
+ getPullRequest: (input) => this.#getPullRequest(input),
227
+ createPullRequest: (input) => this.#createPullRequest(input),
228
+ updatePullRequest: (input) => this.#updatePullRequest(input),
229
+ closePullRequest: (input) => this.#closePullRequest(input),
230
+ mergePullRequest: (input) => this.#mergePullRequest(input),
231
+ listComments: (input) => this.#listComments(input),
232
+ createComment: (input) => this.#createComment(input),
233
+ updateComment: (input) => this.#updateComment(input),
234
+ deleteComment: (input) => this.#deleteComment(input),
235
+ listReviews: (input) => this.#listReviews(input),
236
+ getReview: (input) => this.#getReview(input),
237
+ createReview: (input) => this.#createReview(input),
238
+ updateReview: (input) => this.#updateReview(input),
239
+ submitReview: (input) => this.#submitReview(input),
240
+ dismissReview: (input) => this.#dismissReview(input),
241
+ deletePendingReview: (input) => this.#deletePendingReview(input),
242
+ listReviewComments: (input) => this.#listReviewComments(input),
243
+ createReviewComment: (input) => this.#createReviewComment(input),
244
+ updateReviewComment: (input) => this.#updateReviewComment(input),
245
+ deleteReviewComment: (input) => this.#deleteReviewComment(input),
246
+ listRequestedReviewers: (input) => this.#listRequestedReviewers(input),
247
+ requestReviewers: (input) => this.#requestReviewers(input),
248
+ removeRequestedReviewers: (input) => this.#removeReviewers(input)
249
+ };
250
+ /**
251
+ * The OAuth/install flow round-trips a signed `state` through GitHub, so a
252
+ * multi-replica deploy needs a deployment-stable state secret.
253
+ */
254
+ requiresStableStateSigner = true;
255
+ #appId;
256
+ #privateKey;
257
+ #clientId;
258
+ #clientSecret;
259
+ #slug;
260
+ #webhookSecret;
261
+ #authorizedBots;
262
+ #storage;
263
+ #ingestFactoryEvent;
264
+ #sourceControlStorage;
265
+ /** `installationId:owner/repo:login` → cached collaborator permission (TTL-bounded). */
266
+ #collaboratorPermissionCache = /* @__PURE__ */ new Map();
267
+ /** Same key → lookup already in flight, so overlapping callers share one request. */
268
+ #collaboratorPermissionInFlight = /* @__PURE__ */ new Map();
269
+ /**
270
+ * One Octokit per installation, so its auth instance keeps the installation
271
+ * token cached (auth-app refreshes it before expiry) instead of minting a new
272
+ * token on every call.
273
+ */
274
+ #installationOctokits = /* @__PURE__ */ new Map();
275
+ constructor(config) {
276
+ this.#rules = resolveGithubRules(config.rules);
277
+ const missing = REQUIRED_FIELDS.filter((field) => !config[field]);
278
+ if (missing.length > 0) throw new Error(`GithubIntegration: missing required config field(s): ${missing.join(", ")}. Provide the full GitHub App credentials (appId, privateKey, clientId, clientSecret, slug) or omit the integration to disable GitHub-backed repositories.`);
279
+ this.#appId = config.appId;
280
+ this.#privateKey = normalizePrivateKey(config.privateKey);
281
+ this.#clientId = config.clientId;
282
+ this.#clientSecret = config.clientSecret;
283
+ this.#slug = config.slug;
284
+ this.#webhookSecret = config.webhookSecret || void 0;
285
+ this.#authorizedBots = (config.authorizedBots ?? []).map((bot) => bot.trim()).filter(Boolean);
286
+ }
287
+ /** App slug — the URL name used to build the install URL. */
288
+ get slug() {
289
+ return this.#slug;
290
+ }
291
+ /** Whether a GitHub login belongs to this integration's App. */
292
+ isFactoryCommentAuthor(login) {
293
+ return typeof login === "string" && login.toLowerCase() === `${this.#slug}[bot]`.toLowerCase();
294
+ }
295
+ /** Extra bot logins authorized to trigger author-gated PR notifications. */
296
+ get authorizedBots() {
297
+ return this.#authorizedBots;
298
+ }
299
+ get genericStorage() {
300
+ if (!this.#storage) throw new Error("GithubIntegration storage has not been initialized.");
301
+ return this.#storage.generic;
302
+ }
303
+ get sourceControlStorage() {
304
+ const storage = this.#sourceControlStorage ?? this.#storage?.sourceControl;
305
+ if (!storage) throw new Error("GithubIntegration source-control storage has not been initialized.");
306
+ return storage;
307
+ }
308
+ get integrationStorage() {
309
+ if (!this.#storage) throw new Error("GithubIntegration storage has not been initialized.");
310
+ return this.#storage.generic;
311
+ }
312
+ /** Resolve a stored GitHub locator without scanning installations or repositories. */
313
+ async #resolveIntakeDispatch({ orgId, externalSource }) {
314
+ const target = parseGithubExternalTarget(externalSource.externalId);
315
+ if (!target) return null;
316
+ const repository = await this.sourceControlStorage.repositories.findByExternalId({
317
+ orgId,
318
+ externalId: target.repositoryId
319
+ });
320
+ if (!repository) return null;
321
+ const installation = await this.sourceControlStorage.installations.get({
322
+ orgId,
323
+ id: repository.installationId
324
+ });
325
+ if (!installation) return null;
326
+ const installationId = Number.parseInt(installation.externalId, 10);
327
+ if (!Number.isSafeInteger(installationId)) return null;
328
+ return {
329
+ connection: {
330
+ type: "app-installation",
331
+ installationId
332
+ },
333
+ sourceId: repository.slug,
334
+ issueId: target.issueId
335
+ };
336
+ }
337
+ /** Secret GitHub uses to sign webhook deliveries, when configured. */
338
+ get webhookSecret() {
339
+ return this.#webhookSecret;
340
+ }
341
+ #appAuth() {
342
+ return {
343
+ appId: this.#appId,
344
+ privateKey: this.#privateKey,
345
+ clientId: this.#clientId,
346
+ clientSecret: this.#clientSecret
347
+ };
348
+ }
349
+ /**
350
+ * Octokit authenticated as the GitHub App itself (app JWT). Used for
351
+ * app-level operations and to mint installation tokens.
352
+ */
353
+ getAppOctokit() {
354
+ return new Octokit({
355
+ authStrategy: createAppAuth,
356
+ auth: this.#appAuth()
357
+ });
358
+ }
359
+ /**
360
+ * Octokit authenticated as a specific installation (installation access
361
+ * token). Used to list repos and to operate on a repo on the user's behalf.
362
+ */
363
+ getInstallationOctokit(installationId) {
364
+ let octokit = this.#installationOctokits.get(installationId);
365
+ if (octokit) this.#installationOctokits.delete(installationId);
366
+ else {
367
+ const created = new Octokit({
368
+ authStrategy: createAppAuth,
369
+ auth: {
370
+ ...this.#appAuth(),
371
+ installationId
372
+ }
373
+ });
374
+ created.hook.error("request", (error) => {
375
+ if ("status" in error && error.status === 401 && this.#installationOctokits.get(installationId) === created) this.#installationOctokits.delete(installationId);
376
+ throw error;
377
+ });
378
+ octokit = created;
379
+ if (this.#installationOctokits.size >= INSTALLATION_OCTOKIT_CACHE_MAX_ENTRIES) {
380
+ const oldest = this.#installationOctokits.keys().next().value;
381
+ if (oldest !== void 0) this.#installationOctokits.delete(oldest);
382
+ }
383
+ }
384
+ this.#installationOctokits.set(installationId, octokit);
385
+ return octokit;
386
+ }
387
+ /** Octokit authenticated as a user via their OAuth token (the identify step). */
388
+ getUserOctokit(userToken) {
389
+ return new Octokit({ auth: userToken });
390
+ }
391
+ /**
392
+ * Mint a short-lived installation access token. Returned token is used only
393
+ * server-side / inside the sandbox clone URL and never sent to the browser.
394
+ */
395
+ async mintInstallationToken(installationId) {
396
+ return (await createAppAuth(this.#appAuth())({
397
+ type: "installation",
398
+ installationId
399
+ })).token;
400
+ }
401
+ /**
402
+ * List the installations the authenticated user can access, via their OAuth
403
+ * token (`GET /user/installations`).
404
+ */
405
+ async listUserInstallations(userToken) {
406
+ const octokit = this.getUserOctokit(userToken);
407
+ return (await octokit.paginate(octokit.apps.listInstallationsForAuthenticatedUser, { per_page: 100 })).map((inst) => ({
408
+ installationId: inst.id,
409
+ accountLogin: inst.account && "login" in inst.account ? inst.account.login : null,
410
+ accountType: inst.account && "type" in inst.account ? inst.account.type : null
411
+ }));
412
+ }
413
+ /**
414
+ * List repos accessible to an installation (paginated). Always reads
415
+ * GitHub directly, so `fresh` has nothing to bypass here.
416
+ */
417
+ async listInstallationRepos(installationId, _options) {
418
+ const octokit = this.getInstallationOctokit(installationId);
419
+ return (await octokit.paginate(octokit.apps.listReposAccessibleToInstallation, { per_page: 100 })).map((repo) => ({
420
+ id: repo.id,
421
+ fullName: repo.full_name,
422
+ name: repo.name,
423
+ owner: repo.owner.login,
424
+ defaultBranch: repo.default_branch,
425
+ private: repo.private,
426
+ installationId
427
+ }));
428
+ }
429
+ /**
430
+ * The authenticated user's permission level on a repo, through the
431
+ * installation. `undefined` when the repo/user is not accessible.
432
+ */
433
+ async getRepositoryCollaboratorPermission(installationId, repoFullName, username, signal) {
434
+ const parts = splitRepoFullName(repoFullName);
435
+ if (!parts) return void 0;
436
+ const cacheKey = `${installationId}:${parts.owner}/${parts.repo}:${username.toLowerCase()}`;
437
+ const cached = this.#collaboratorPermissionCache.get(cacheKey);
438
+ if (cached && cached.expiresAt > Date.now()) return cached.permission;
439
+ this.#collaboratorPermissionCache.delete(cacheKey);
440
+ const inFlight = this.#collaboratorPermissionInFlight.get(cacheKey);
441
+ if (inFlight) return settleOrAbort(inFlight, signal, void 0);
442
+ const lookup = (async () => {
443
+ try {
444
+ const { data } = await this.getInstallationOctokit(installationId).repos.getCollaboratorPermissionLevel({
445
+ ...parts,
446
+ username,
447
+ request: { signal: AbortSignal.timeout(COLLABORATOR_PERMISSION_LOOKUP_TIMEOUT_MS) }
448
+ });
449
+ const permission = data.permission;
450
+ this.#collaboratorPermissionCache.set(cacheKey, {
451
+ permission,
452
+ expiresAt: Date.now() + COLLABORATOR_PERMISSION_CACHE_TTL_MS
453
+ });
454
+ if (this.#collaboratorPermissionCache.size > COLLABORATOR_PERMISSION_CACHE_MAX_ENTRIES) {
455
+ const oldest = this.#collaboratorPermissionCache.keys().next().value;
456
+ if (oldest !== void 0) this.#collaboratorPermissionCache.delete(oldest);
457
+ }
458
+ return permission;
459
+ } catch {
460
+ return;
461
+ } finally {
462
+ this.#collaboratorPermissionInFlight.delete(cacheKey);
463
+ }
464
+ })();
465
+ this.#collaboratorPermissionInFlight.set(cacheKey, lookup);
466
+ return settleOrAbort(lookup, signal, void 0);
467
+ }
468
+ /**
469
+ * Fetch a single repo's metadata through an installation token and confirm
470
+ * the installation actually has access to it. Returns `null` when the repo
471
+ * is not accessible to the installation (so a client can't create a project
472
+ * for an arbitrary repo under an installation id it merely owns).
473
+ */
474
+ async getInstallationRepo(installationId, repoFullName) {
475
+ const parts = splitRepoFullName(repoFullName);
476
+ if (!parts) return null;
477
+ const octokit = this.getInstallationOctokit(installationId);
478
+ try {
479
+ const { data } = await octokit.repos.get(parts);
480
+ return {
481
+ id: data.id,
482
+ fullName: data.full_name,
483
+ name: data.name,
484
+ owner: data.owner.login,
485
+ defaultBranch: data.default_branch,
486
+ private: data.private,
487
+ installationId
488
+ };
489
+ } catch {
490
+ return null;
491
+ }
492
+ }
493
+ async #listIntakeIssues(input) {
494
+ const installationId = getGithubInstallationId(input.connection);
495
+ const repoFullName = getSingleSourceId(input.sourceIds, "GitHub Intake requires exactly one repository source.");
496
+ const page = parsePositiveCursor(input.cursor);
497
+ const labels = normalizeLabels(input.labels);
498
+ const result = await this.listRepoOpenIssues(installationId, repoFullName, page, { label: labels.length > 0 ? labels.join(",") : void 0 });
499
+ return {
500
+ issues: result.issues.map((issue) => ({
501
+ id: String(issue.number),
502
+ identifier: `#${issue.number}`,
503
+ title: issue.title,
504
+ url: issue.url,
505
+ author: issue.author,
506
+ state: "open",
507
+ stateType: "open",
508
+ priority: null,
509
+ assignee: issue.assignees[0] ?? null,
510
+ assignees: issue.assignees,
511
+ source: repoFullName,
512
+ labels: issue.labels,
513
+ commentCount: issue.comments,
514
+ createdAt: issue.createdAt,
515
+ updatedAt: issue.updatedAt
516
+ })),
517
+ nextCursor: result.nextPage === null ? null : String(result.nextPage)
518
+ };
519
+ }
520
+ async #getIntakeIssue(input) {
521
+ const installationId = getGithubInstallationId(input.connection);
522
+ const repoFullName = requireSourceId(input.sourceId, "GitHub Intake requires a repository source.");
523
+ const parts = splitRepoFullName(repoFullName);
524
+ const issueNumber = parsePositiveInteger(input.issueId);
525
+ if (!parts || issueNumber === null) return null;
526
+ const octokit = this.getInstallationOctokit(installationId);
527
+ try {
528
+ const [{ data: issue }, comments] = await Promise.all([octokit.issues.get({
529
+ owner: parts.owner,
530
+ repo: parts.repo,
531
+ issue_number: issueNumber
532
+ }), octokit.paginate(octokit.issues.listComments, {
533
+ owner: parts.owner,
534
+ repo: parts.repo,
535
+ issue_number: issueNumber,
536
+ per_page: 100
537
+ })]);
538
+ if (issue.pull_request) return null;
539
+ return {
540
+ id: String(issue.number),
541
+ identifier: `#${issue.number}`,
542
+ title: issue.title,
543
+ url: issue.html_url,
544
+ author: issue.user?.login ?? null,
545
+ state: issue.state,
546
+ stateType: issue.state,
547
+ priority: null,
548
+ assignee: issue.assignee?.login ?? null,
549
+ assignees: (issue.assignees ?? []).map((user) => user.login).filter((login) => Boolean(login)),
550
+ source: repoFullName,
551
+ labels: issue.labels.map((label) => typeof label === "string" ? label : label.name ?? "").filter(Boolean),
552
+ commentCount: issue.comments,
553
+ createdAt: issue.created_at,
554
+ updatedAt: issue.updated_at,
555
+ description: issue.body?.trim() ? issue.body : null,
556
+ comments: comments.map((comment) => ({
557
+ author: comment.user?.login ?? null,
558
+ body: comment.body ?? "",
559
+ createdAt: comment.created_at
560
+ }))
561
+ };
562
+ } catch (err) {
563
+ if (isNotFoundError(err)) return null;
564
+ throw err;
565
+ }
566
+ }
567
+ async #updateIntakeIssue(input) {
568
+ const installationId = getGithubInstallationId(input.connection);
569
+ const repoFullName = requireSourceId(input.sourceId, "GitHub Intake requires a repository source.");
570
+ const parts = splitRepoFullName(repoFullName);
571
+ const issueNumber = parsePositiveInteger(input.issueId);
572
+ if (!parts || issueNumber === null) return null;
573
+ if (input.state.kind === "byName") {
574
+ console.warn(`GitHub integration: updateIssue byName is not supported (name=${input.state.name}); ignoring.`);
575
+ return null;
576
+ }
577
+ const targetState = input.state.stateType === "unstarted" || input.state.stateType === "started" ? "open" : "closed";
578
+ const stateReason = targetState === "closed" ? input.state.stateType === "canceled" ? "not_planned" : "completed" : null;
579
+ const octokit = this.getInstallationOctokit(installationId);
580
+ try {
581
+ const { data: current } = await octokit.issues.get({
582
+ owner: parts.owner,
583
+ repo: parts.repo,
584
+ issue_number: issueNumber
585
+ });
586
+ if (current.pull_request) {
587
+ console.warn(`GitHub integration: updateIssue rejected — target ${repoFullName}#${issueNumber} is a pull request.`);
588
+ return null;
589
+ }
590
+ const { data: issue } = await octokit.issues.update({
591
+ owner: parts.owner,
592
+ repo: parts.repo,
593
+ issue_number: issueNumber,
594
+ state: targetState,
595
+ ...stateReason ? { state_reason: stateReason } : {}
596
+ });
597
+ return {
598
+ id: String(issue.number),
599
+ identifier: `#${issue.number}`,
600
+ title: issue.title,
601
+ url: issue.html_url,
602
+ author: issue.user?.login ?? null,
603
+ state: issue.state,
604
+ stateType: issue.state,
605
+ priority: null,
606
+ assignee: issue.assignee?.login ?? null,
607
+ assignees: (issue.assignees ?? []).map((user) => user.login).filter((login) => Boolean(login)),
608
+ source: repoFullName,
609
+ labels: issue.labels.map((label) => typeof label === "string" ? label : label.name ?? "").filter(Boolean),
610
+ commentCount: issue.comments,
611
+ createdAt: issue.created_at,
612
+ updatedAt: issue.updated_at
613
+ };
614
+ } catch (err) {
615
+ if (isNotFoundError(err)) return null;
616
+ throw err;
617
+ }
618
+ }
619
+ async #createIntakeComment(input) {
620
+ const installationId = getGithubInstallationId(input.connection);
621
+ const parts = splitRepoFullName(requireSourceId(input.sourceId, "GitHub Intake requires a repository source."));
622
+ const issueNumber = parsePositiveInteger(input.issueId);
623
+ if (!parts || issueNumber === null) return null;
624
+ const octokit = this.getInstallationOctokit(installationId);
625
+ try {
626
+ const { data } = await octokit.issues.createComment({
627
+ owner: parts.owner,
628
+ repo: parts.repo,
629
+ issue_number: issueNumber,
630
+ body: input.body
631
+ });
632
+ return {
633
+ id: String(data.id),
634
+ url: data.html_url
635
+ };
636
+ } catch (err) {
637
+ if (isNotFoundError(err)) return null;
638
+ throw err;
639
+ }
640
+ }
641
+ #repositoryClient(connection, sourceId) {
642
+ const installationId = getGithubInstallationId(connection);
643
+ const parts = splitRepoFullName(sourceId);
644
+ if (!parts) throw new Error("GitHub pull requests require an owner/repository source.");
645
+ return {
646
+ octokit: this.getInstallationOctokit(installationId),
647
+ parts
648
+ };
649
+ }
650
+ async #listPullRequests(input) {
651
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
652
+ const page = parsePositiveCursor(input.cursor);
653
+ const response = await octokit.pulls.list({
654
+ ...parts,
655
+ state: input.state ?? "open",
656
+ per_page: 30,
657
+ page
658
+ });
659
+ return {
660
+ pullRequests: response.data.filter((pr) => input.includeDrafts !== false || !pr.draft).map((pr) => parsePullRequest(pr)),
661
+ nextCursor: response.data.length === 30 ? String(page + 1) : null
662
+ };
663
+ }
664
+ async #getPullRequest(input) {
665
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
666
+ const pullNumber = requirePullRequestNumber(input.pullRequestId);
667
+ try {
668
+ const { data } = await octokit.pulls.get({
669
+ ...parts,
670
+ pull_number: pullNumber
671
+ });
672
+ return parsePullRequest(data);
673
+ } catch (err) {
674
+ if (isNotFoundError(err)) return null;
675
+ throw err;
676
+ }
677
+ }
678
+ async #createPullRequest(input) {
679
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
680
+ const { data } = await octokit.pulls.create({
681
+ ...parts,
682
+ title: input.title,
683
+ body: input.body,
684
+ base: input.baseBranch,
685
+ head: input.headBranch,
686
+ draft: input.draft
687
+ });
688
+ return parsePullRequest(data);
689
+ }
690
+ async #updatePullRequest(input) {
691
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
692
+ const { data } = await octokit.pulls.update({
693
+ ...parts,
694
+ pull_number: requirePullRequestNumber(input.pullRequestId),
695
+ title: input.title,
696
+ body: input.body === null ? "" : input.body,
697
+ base: input.baseBranch,
698
+ state: input.state
699
+ });
700
+ return parsePullRequest(data);
701
+ }
702
+ async #closePullRequest(input) {
703
+ return this.#updatePullRequest({
704
+ ...input,
705
+ state: "closed"
706
+ });
707
+ }
708
+ async #mergePullRequest(input) {
709
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
710
+ const { data } = await octokit.pulls.merge({
711
+ ...parts,
712
+ pull_number: requirePullRequestNumber(input.pullRequestId),
713
+ commit_title: input.commitTitle,
714
+ commit_message: input.commitMessage,
715
+ merge_method: input.method
716
+ });
717
+ return {
718
+ merged: data.merged,
719
+ message: data.message,
720
+ sha: data.sha ?? null
721
+ };
722
+ }
723
+ async #listComments(input) {
724
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
725
+ const page = parsePositiveCursor(input.cursor);
726
+ const response = await octokit.issues.listComments({
727
+ ...parts,
728
+ issue_number: requirePullRequestNumber(input.pullRequestId),
729
+ per_page: 30,
730
+ page
731
+ });
732
+ return {
733
+ comments: response.data.map((comment) => parsePullRequestComment(comment)),
734
+ nextCursor: response.data.length === 30 ? String(page + 1) : null
735
+ };
736
+ }
737
+ async #createComment(input) {
738
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
739
+ const { data } = await octokit.issues.createComment({
740
+ ...parts,
741
+ issue_number: requirePullRequestNumber(input.pullRequestId),
742
+ body: input.body
743
+ });
744
+ return parsePullRequestComment(data);
745
+ }
746
+ async #updateComment(input) {
747
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
748
+ const { data } = await octokit.issues.updateComment({
749
+ ...parts,
750
+ comment_id: requirePositiveId(input.commentId, "comment"),
751
+ body: input.body
752
+ });
753
+ return parsePullRequestComment(data);
754
+ }
755
+ async #deleteComment(input) {
756
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
757
+ await octokit.issues.deleteComment({
758
+ ...parts,
759
+ comment_id: requirePositiveId(input.commentId, "comment")
760
+ });
761
+ }
762
+ async #listReviews(input) {
763
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
764
+ const page = parsePositiveCursor(input.cursor);
765
+ const response = await octokit.pulls.listReviews({
766
+ ...parts,
767
+ pull_number: requirePullRequestNumber(input.pullRequestId),
768
+ per_page: 30,
769
+ page
770
+ });
771
+ return {
772
+ reviews: response.data.map((review) => parseReview(review)),
773
+ nextCursor: response.data.length === 30 ? String(page + 1) : null
774
+ };
775
+ }
776
+ async #getReview(input) {
777
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
778
+ try {
779
+ const { data } = await octokit.pulls.getReview({
780
+ ...parts,
781
+ pull_number: requirePullRequestNumber(input.pullRequestId),
782
+ review_id: requirePositiveId(input.reviewId, "review")
783
+ });
784
+ return parseReview(data);
785
+ } catch (err) {
786
+ if (isNotFoundError(err)) return null;
787
+ throw err;
788
+ }
789
+ }
790
+ async #createReview(input) {
791
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
792
+ const { data } = await octokit.pulls.createReview({
793
+ ...parts,
794
+ pull_number: requirePullRequestNumber(input.pullRequestId),
795
+ body: input.body,
796
+ commit_id: input.commitId,
797
+ event: input.event ? reviewEventToGithub(input.event) : void 0
798
+ });
799
+ return parseReview(data);
800
+ }
801
+ async #updateReview(input) {
802
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
803
+ const { data } = await octokit.pulls.updateReview({
804
+ ...parts,
805
+ pull_number: requirePullRequestNumber(input.pullRequestId),
806
+ review_id: requirePositiveId(input.reviewId, "review"),
807
+ body: input.body
808
+ });
809
+ return parseReview(data);
810
+ }
811
+ async #submitReview(input) {
812
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
813
+ const { data } = await octokit.pulls.submitReview({
814
+ ...parts,
815
+ pull_number: requirePullRequestNumber(input.pullRequestId),
816
+ review_id: requirePositiveId(input.reviewId, "review"),
817
+ body: input.body,
818
+ event: reviewEventToGithub(input.event)
819
+ });
820
+ return parseReview(data);
821
+ }
822
+ async #dismissReview(input) {
823
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
824
+ const { data } = await octokit.pulls.dismissReview({
825
+ ...parts,
826
+ pull_number: requirePullRequestNumber(input.pullRequestId),
827
+ review_id: requirePositiveId(input.reviewId, "review"),
828
+ message: input.message
829
+ });
830
+ return parseReview(data);
831
+ }
832
+ async #deletePendingReview(input) {
833
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
834
+ await octokit.pulls.deletePendingReview({
835
+ ...parts,
836
+ pull_number: requirePullRequestNumber(input.pullRequestId),
837
+ review_id: requirePositiveId(input.reviewId, "review")
838
+ });
839
+ }
840
+ async #listReviewComments(input) {
841
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
842
+ const page = parsePositiveCursor(input.cursor);
843
+ const response = await octokit.pulls.listReviewComments({
844
+ ...parts,
845
+ pull_number: requirePullRequestNumber(input.pullRequestId),
846
+ per_page: 30,
847
+ page
848
+ });
849
+ return {
850
+ comments: response.data.map((comment) => parseReviewComment(comment)),
851
+ nextCursor: response.data.length === 30 ? String(page + 1) : null
852
+ };
853
+ }
854
+ async #createReviewComment(input) {
855
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
856
+ const pullNumber = requirePullRequestNumber(input.pullRequestId);
857
+ if (input.replyToId) {
858
+ const { data } = await octokit.pulls.createReplyForReviewComment({
859
+ ...parts,
860
+ pull_number: pullNumber,
861
+ comment_id: requirePositiveId(input.replyToId, "review comment"),
862
+ body: input.body
863
+ });
864
+ return parseReviewComment(data);
865
+ }
866
+ if (!input.commitId || !input.path || input.line === void 0 || !input.side) throw new Error("A review comment requires commitId, path, line, and side unless it is a reply.");
867
+ if (input.startLine === void 0 !== (input.startSide === void 0)) throw new Error("A multi-line review comment requires both startLine and startSide.");
868
+ const { data } = await octokit.pulls.createReviewComment({
869
+ ...parts,
870
+ pull_number: pullNumber,
871
+ body: input.body,
872
+ commit_id: input.commitId,
873
+ path: input.path,
874
+ line: input.line,
875
+ side: input.side.toUpperCase(),
876
+ start_line: input.startLine,
877
+ start_side: input.startSide?.toUpperCase()
878
+ });
879
+ return parseReviewComment(data);
880
+ }
881
+ async #updateReviewComment(input) {
882
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
883
+ const { data } = await octokit.pulls.updateReviewComment({
884
+ ...parts,
885
+ comment_id: requirePositiveId(input.commentId, "review comment"),
886
+ body: input.body
887
+ });
888
+ return parseReviewComment(data);
889
+ }
890
+ async #deleteReviewComment(input) {
891
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
892
+ await octokit.pulls.deleteReviewComment({
893
+ ...parts,
894
+ comment_id: requirePositiveId(input.commentId, "review comment")
895
+ });
896
+ }
897
+ async #listRequestedReviewers(input) {
898
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
899
+ const { data } = await octokit.pulls.listRequestedReviewers({
900
+ ...parts,
901
+ pull_number: requirePullRequestNumber(input.pullRequestId)
902
+ });
903
+ return parseRequestedReviewers(data);
904
+ }
905
+ async #requestReviewers(input) {
906
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
907
+ const { data } = await octokit.pulls.requestReviewers({
908
+ ...parts,
909
+ pull_number: requirePullRequestNumber(input.pullRequestId),
910
+ reviewers: input.users ?? [],
911
+ team_reviewers: input.teams ?? []
912
+ });
913
+ return parseRequestedReviewers(data);
914
+ }
915
+ async #removeReviewers(input) {
916
+ const { octokit, parts } = this.#repositoryClient(input.connection, input.sourceId);
917
+ const { data } = await octokit.pulls.removeRequestedReviewers({
918
+ ...parts,
919
+ pull_number: requirePullRequestNumber(input.pullRequestId),
920
+ reviewers: input.users ?? [],
921
+ team_reviewers: input.teams ?? []
922
+ });
923
+ return parseRequestedReviewers(data);
924
+ }
925
+ /** Add labels to an issue (deduplicated; no-op on empty/malformed input). */
926
+ async addIssueLabels(installationId, repoFullName, issueNumber, labels) {
927
+ const parts = splitRepoFullName(repoFullName);
928
+ if (!parts) return;
929
+ const uniqueLabels = [...new Set(labels.map((label) => label.trim()).filter(Boolean))];
930
+ if (uniqueLabels.length === 0) return;
931
+ await this.getInstallationOctokit(installationId).issues.addLabels({
932
+ owner: parts.owner,
933
+ repo: parts.repo,
934
+ issue_number: issueNumber,
935
+ labels: uniqueLabels
936
+ });
937
+ }
938
+ /** Remove one label from an issue. */
939
+ async removeIssueLabel(installationId, repoFullName, issueNumber, label) {
940
+ const parts = splitRepoFullName(repoFullName);
941
+ const labelName = label.trim();
942
+ if (!parts || !labelName) return;
943
+ await this.getInstallationOctokit(installationId).issues.removeLabel({
944
+ owner: parts.owner,
945
+ repo: parts.repo,
946
+ issue_number: issueNumber,
947
+ name: labelName
948
+ });
949
+ }
950
+ /**
951
+ * List one page of a repo's open issues through an installation token. The
952
+ * issues API also returns pull requests, so those are filtered out (the
953
+ * filter can make a non-final page shorter than the page size — `nextPage`
954
+ * is derived from the raw response length, not the filtered one).
955
+ */
956
+ async listRepoOpenIssues(installationId, repoFullName, page, options = {}) {
957
+ const parts = splitRepoFullName(repoFullName);
958
+ if (!parts) return {
959
+ issues: [],
960
+ nextPage: null
961
+ };
962
+ const response = await this.getInstallationOctokit(installationId).issues.listForRepo({
963
+ owner: parts.owner,
964
+ repo: parts.repo,
965
+ state: "open",
966
+ labels: options.label,
967
+ per_page: 30,
968
+ page
969
+ });
970
+ return {
971
+ issues: response.data.filter((issue) => !issue.pull_request).map((issue) => ({
972
+ number: issue.number,
973
+ title: issue.title,
974
+ url: issue.html_url,
975
+ author: issue.user?.login ?? null,
976
+ assignees: issue.assignees?.flatMap((assignee) => assignee.login ? [assignee.login] : []) ?? [],
977
+ labels: issue.labels.map((label) => typeof label === "string" ? label : label.name ?? "").filter(Boolean),
978
+ comments: issue.comments,
979
+ createdAt: issue.created_at,
980
+ updatedAt: issue.updated_at
981
+ })),
982
+ nextPage: response.data.length === 30 ? page + 1 : null
983
+ };
984
+ }
985
+ /**
986
+ * Build the GitHub App install URL. `state` is carried through the install
987
+ * flow and validated on callback.
988
+ */
989
+ buildInstallUrl(state) {
990
+ const url = new URL(`https://github.com/apps/${this.#slug}/installations/new`);
991
+ url.searchParams.set("state", state);
992
+ return url.toString();
993
+ }
994
+ /**
995
+ * Build the OAuth identify URL (authorize) used to confirm the user's
996
+ * identity and obtain a user token for listing their installations.
997
+ */
998
+ buildOAuthIdentifyUrl(state, redirectUri) {
999
+ const url = new URL("https://github.com/login/oauth/authorize");
1000
+ url.searchParams.set("client_id", this.#clientId);
1001
+ url.searchParams.set("redirect_uri", redirectUri);
1002
+ url.searchParams.set("state", state);
1003
+ return url.toString();
1004
+ }
1005
+ /** Exchange an OAuth `code` for a user access token. */
1006
+ async exchangeOAuthCode(code, redirectUri) {
1007
+ const res = await fetch("https://github.com/login/oauth/access_token", {
1008
+ method: "POST",
1009
+ signal: AbortSignal.timeout(GITHUB_OAUTH_TOKEN_TIMEOUT_MS),
1010
+ headers: {
1011
+ "content-type": "application/json",
1012
+ accept: "application/json"
1013
+ },
1014
+ body: JSON.stringify({
1015
+ client_id: this.#clientId,
1016
+ client_secret: this.#clientSecret,
1017
+ code,
1018
+ redirect_uri: redirectUri
1019
+ })
1020
+ });
1021
+ if (!res.ok) throw new Error(`GitHub OAuth token exchange failed: ${res.status}`);
1022
+ const data = await res.json();
1023
+ if (!data.access_token) throw new Error(`GitHub OAuth token exchange returned no token: ${data.error_description ?? data.error ?? "unknown"}`);
1024
+ return data.access_token;
1025
+ }
1026
+ /**
1027
+ * The integration's HTTP surface: the `/web/github/*` + `/auth/github/*`
1028
+ * Mastra `apiRoutes` (webhook handler, install/OAuth flow, project +
1029
+ * worktree + session operations). The factory folds these into the server's
1030
+ * `apiRoutes` when the feature is ready. Handlers operate on this instance.
1031
+ */
1032
+ routes(ctx) {
1033
+ this.#storage = ctx.storage;
1034
+ const ingestFactoryEvent = attachGithubRules(this, ctx);
1035
+ this.#ingestFactoryEvent = ingestFactoryEvent;
1036
+ return buildGithubRoutes({
1037
+ github: this,
1038
+ auth: ctx.auth,
1039
+ sandbox: ctx.sandbox,
1040
+ ...ctx.users ? { users: ctx.users } : {},
1041
+ storage: ctx.factoryStorage,
1042
+ stateSigner: ctx.stateSigner,
1043
+ baseUrl: ctx.baseUrl,
1044
+ controller: ctx.controller,
1045
+ memorySettings: ctx.storage.memorySettings,
1046
+ emitAudit: ctx.hooks?.emitAudit,
1047
+ projects: ctx.storage.projects,
1048
+ ingestFactoryEvent,
1049
+ sessionRetirement: ctx.sessionRetirement,
1050
+ ...ctx.workItems ? { workItems: ctx.workItems } : {}
1051
+ });
1052
+ }
1053
+ /**
1054
+ * Import a newly linked repository's open issues and pull requests onto
1055
+ * the board. No-op until routes are mounted with rules configured.
1056
+ */
1057
+ async ingestLinkedRepositoryBacklog(args) {
1058
+ await ingestLinkedRepositoryBacklog({
1059
+ github: this,
1060
+ ...args,
1061
+ ingestFactoryEvent: this.#ingestFactoryEvent
1062
+ });
1063
+ }
1064
+ /**
1065
+ * Pull-request and issue sweeps share a worker and lease, but can be enabled
1066
+ * and paced independently. The legacy combined controls remain the fallback.
1067
+ */
1068
+ workers(ctx) {
1069
+ const pullRequestEnabled = reconciliationEnabled(process.env.MASTRACODE_GITHUB_PR_RECONCILE_ENABLED, process.env.MASTRACODE_GITHUB_RECONCILE_ENABLED);
1070
+ const issueEnabled = reconciliationEnabled(process.env.MASTRACODE_GITHUB_ISSUE_RECONCILE_ENABLED, process.env.MASTRACODE_GITHUB_RECONCILE_ENABLED);
1071
+ if (!pullRequestEnabled && !issueEnabled) return [];
1072
+ const reconcile = pullRequestEnabled ? attachGithubReconciler(this, ctx, (input) => this.fetchPullRequestState(input)) : void 0;
1073
+ const issues = issueEnabled ? attachGithubIssueReconciler(this, ctx, (input) => this.fetchIssueState(input), (input) => this.listOpenIssueStates(input)) : void 0;
1074
+ if (!reconcile && !issues) return [];
1075
+ const legacyInterval = reconcileInterval(process.env.MASTRACODE_GITHUB_RECONCILE_INTERVAL_MS);
1076
+ const intervalMs = reconcileInterval(process.env.MASTRACODE_GITHUB_PR_RECONCILE_INTERVAL_MS) ?? legacyInterval;
1077
+ const issueIntervalMs = reconcileInterval(process.env.MASTRACODE_GITHUB_ISSUE_RECONCILE_INTERVAL_MS) ?? legacyInterval;
1078
+ return [new GithubReconcileWorker({
1079
+ ...reconcile ? { reconcile } : {},
1080
+ ...issues ? { reconcileIssues: issues } : {},
1081
+ sourceControl: ctx.storage.sourceControl,
1082
+ ...intervalMs ? { intervalMs } : {},
1083
+ ...issueIntervalMs ? { issueIntervalMs } : {}
1084
+ })];
1085
+ }
1086
+ /**
1087
+ * Reads live PR state for the merge reconciler. Returns undefined when the PR
1088
+ * cannot be resolved so a sweep never fabricates a merge.
1089
+ */
1090
+ async fetchPullRequestState(input) {
1091
+ try {
1092
+ const pullRequest = await this.#getPullRequest({
1093
+ connection: {
1094
+ type: "app-installation",
1095
+ installationId: input.installationId
1096
+ },
1097
+ sourceId: input.repository,
1098
+ pullRequestId: String(input.number)
1099
+ });
1100
+ if (!pullRequest) return void 0;
1101
+ return {
1102
+ title: pullRequest.title,
1103
+ url: pullRequest.url,
1104
+ state: pullRequest.state === "closed" ? "closed" : "open",
1105
+ draft: pullRequest.draft,
1106
+ merged: pullRequest.merged,
1107
+ assignees: pullRequest.assignees ?? [],
1108
+ requestedReviewers: pullRequest.requestedReviewers ?? [],
1109
+ labels: pullRequest.labels ?? [],
1110
+ headBranch: pullRequest.headBranch,
1111
+ baseBranch: pullRequest.baseBranch,
1112
+ ...pullRequest.author ? { author: pullRequest.author } : {},
1113
+ ...pullRequest.createdAt ? { createdAt: pullRequest.createdAt } : {}
1114
+ };
1115
+ } catch {
1116
+ return;
1117
+ }
1118
+ }
1119
+ /**
1120
+ * Reads live issue state for the reconciler. Returns undefined when the
1121
+ * issue cannot be resolved (missing, is actually a PR, API error) so a
1122
+ * sweep never fabricates a close.
1123
+ */
1124
+ async fetchIssueState(input) {
1125
+ const parts = splitRepoFullName(input.repository);
1126
+ if (!parts) return void 0;
1127
+ try {
1128
+ const { data: issue } = await this.getInstallationOctokit(input.installationId).issues.get({
1129
+ owner: parts.owner,
1130
+ repo: parts.repo,
1131
+ issue_number: input.number
1132
+ });
1133
+ if (issue.pull_request) return void 0;
1134
+ return {
1135
+ title: issue.title,
1136
+ url: issue.html_url,
1137
+ state: issue.state === "closed" ? "closed" : "open",
1138
+ ...issue.state_reason ? { stateReason: issue.state_reason } : {},
1139
+ assignees: (issue.assignees ?? []).map((user) => user.login).filter((login) => Boolean(login)),
1140
+ labels: (issue.labels ?? []).map((label) => typeof label === "string" ? label : label.name).filter((name) => Boolean(name)),
1141
+ ...issue.user?.login ? { author: issue.user.login } : {},
1142
+ createdAt: issue.created_at,
1143
+ updatedAt: issue.updated_at
1144
+ };
1145
+ } catch {
1146
+ return;
1147
+ }
1148
+ }
1149
+ /**
1150
+ * Lists a repository's open issues (pull requests excluded) so the issue
1151
+ * sweep can mint cards for issues whose webhook never arrived.
1152
+ */
1153
+ async listOpenIssueStates(input) {
1154
+ const parts = splitRepoFullName(input.repository);
1155
+ if (!parts) return [];
1156
+ const octokit = this.getInstallationOctokit(input.installationId);
1157
+ const issues = [];
1158
+ for (let page = 1; page <= OPEN_ISSUE_DISCOVERY_MAX_PAGES; page += 1) {
1159
+ const { data } = await octokit.issues.listForRepo({
1160
+ owner: parts.owner,
1161
+ repo: parts.repo,
1162
+ state: "open",
1163
+ per_page: OPEN_ISSUE_DISCOVERY_PAGE_SIZE,
1164
+ page
1165
+ });
1166
+ for (const issue of data) {
1167
+ if (issue.pull_request) continue;
1168
+ issues.push({
1169
+ number: issue.number,
1170
+ title: issue.title,
1171
+ url: issue.html_url,
1172
+ state: "open",
1173
+ assignees: (issue.assignees ?? []).map((user) => user.login).filter((login) => Boolean(login)),
1174
+ labels: (issue.labels ?? []).map((label) => typeof label === "string" ? label : label.name).filter((name) => Boolean(name)),
1175
+ ...issue.user?.login ? { author: issue.user.login } : {},
1176
+ createdAt: issue.created_at,
1177
+ updatedAt: issue.updated_at
1178
+ });
1179
+ }
1180
+ if (data.length < OPEN_ISSUE_DISCOVERY_PAGE_SIZE) break;
1181
+ }
1182
+ return issues;
1183
+ }
1184
+ /**
1185
+ * Session-scoped agent tools for token refresh and PR subscriptions in
1186
+ * sessions bound to a GitHub-backed project. Empty elsewhere.
1187
+ */
1188
+ async upsertFactoryTriageComment(input) {
1189
+ const parts = splitRepoFullName(input.repository);
1190
+ if (!parts) throw new Error("GitHub triage comments require an owner/repository source.");
1191
+ const octokit = this.getInstallationOctokit(input.installationId);
1192
+ const comments = [];
1193
+ for (let page = 1;; page += 1) {
1194
+ const response = await octokit.issues.listComments({
1195
+ ...parts,
1196
+ issue_number: input.issueNumber,
1197
+ per_page: 100,
1198
+ page
1199
+ });
1200
+ comments.push(...response.data);
1201
+ if (response.data.length < 100) break;
1202
+ }
1203
+ const existing = comments.filter((comment) => comment.body?.includes("<!-- mastra-factory-triage -->") && this.isFactoryCommentAuthor(comment.user?.login)).sort((left, right) => left.id - right.id)[0];
1204
+ if (existing) {
1205
+ const { data } = await octokit.issues.updateComment({
1206
+ ...parts,
1207
+ comment_id: existing.id,
1208
+ body: input.body
1209
+ });
1210
+ return {
1211
+ action: "updated",
1212
+ commentId: String(data.id),
1213
+ url: data.html_url
1214
+ };
1215
+ }
1216
+ const { data } = await octokit.issues.createComment({
1217
+ ...parts,
1218
+ issue_number: input.issueNumber,
1219
+ body: input.body
1220
+ });
1221
+ return {
1222
+ action: "created",
1223
+ commentId: String(data.id),
1224
+ url: data.html_url
1225
+ };
1226
+ }
1227
+ sessionTools({ requestContext }) {
1228
+ return createGithubSubscriptionTools(requestContext, this);
1229
+ }
1230
+ async postToolObserver({ toolContext, requestContext }) {
1231
+ const pullRequestUrl = parseCreatedPullRequest(toolContext);
1232
+ if (!pullRequestUrl || !requestContext) return;
1233
+ await subscribeCurrentSessionToPullRequest(requestContext, pullRequestUrl, "auto-gh-pr-create", this);
1234
+ }
1235
+ /** Non-secret config snapshot for system diagnostics/startup logs. */
1236
+ diagnostics() {
1237
+ return {
1238
+ slug: this.#slug,
1239
+ webhookSecretConfigured: this.#webhookSecret !== void 0
1240
+ };
1241
+ }
1242
+ };
1243
+ function parsePullRequest(pr) {
1244
+ return {
1245
+ id: String(pr.number),
1246
+ title: pr.title,
1247
+ url: pr.html_url,
1248
+ author: pr.user?.login ?? null,
1249
+ assignees: (pr.assignees ?? []).flatMap((assignee) => assignee.login ? [assignee.login] : []),
1250
+ requestedReviewers: (pr.requested_reviewers ?? []).flatMap((reviewer) => reviewer.login ? [reviewer.login] : []),
1251
+ labels: (pr.labels ?? []).flatMap((label) => typeof label === "string" ? [label] : label.name ? [label.name] : []),
1252
+ body: pr.body?.trim() ? pr.body : null,
1253
+ state: pr.state === "closed" ? "closed" : "open",
1254
+ draft: pr.draft ?? false,
1255
+ merged: pr.merged ?? Boolean(pr.merged_at),
1256
+ mergeable: typeof pr.mergeable === "boolean" ? pr.mergeable : null,
1257
+ baseBranch: pr.base.ref,
1258
+ headBranch: pr.head.ref,
1259
+ headSha: pr.head.sha,
1260
+ createdAt: pr.created_at,
1261
+ updatedAt: pr.updated_at
1262
+ };
1263
+ }
1264
+ function parsePullRequestComment(comment) {
1265
+ return {
1266
+ id: String(comment.id),
1267
+ url: comment.html_url,
1268
+ author: comment.user?.login ?? null,
1269
+ body: comment.body ?? "",
1270
+ createdAt: comment.created_at,
1271
+ updatedAt: comment.updated_at
1272
+ };
1273
+ }
1274
+ function parseReview(review) {
1275
+ return {
1276
+ id: String(review.id),
1277
+ url: review.html_url ?? null,
1278
+ author: review.user?.login ?? null,
1279
+ body: review.body?.trim() ? review.body : null,
1280
+ state: parseReviewState(review.state),
1281
+ commitId: review.commit_id ?? null,
1282
+ submittedAt: review.submitted_at ?? null
1283
+ };
1284
+ }
1285
+ function parseReviewComment(comment) {
1286
+ const parsed = parsePullRequestComment(comment);
1287
+ const side = comment.side?.toLowerCase();
1288
+ return {
1289
+ ...parsed,
1290
+ path: comment.path,
1291
+ line: comment.line ?? null,
1292
+ side: side === "left" || side === "right" ? side : null,
1293
+ commitId: comment.commit_id,
1294
+ replyToId: comment.in_reply_to_id ? String(comment.in_reply_to_id) : null
1295
+ };
1296
+ }
1297
+ function parseRequestedReviewers(data) {
1298
+ return {
1299
+ users: (data.users ?? data.requested_reviewers ?? []).flatMap((user) => user.login ? [user.login] : []),
1300
+ teams: (data.teams ?? data.requested_teams ?? []).flatMap((team) => team.slug ? [team.slug] : [])
1301
+ };
1302
+ }
1303
+ function parseReviewState(state) {
1304
+ if (state === "PENDING") return "pending";
1305
+ if (state === "COMMENTED") return "commented";
1306
+ if (state === "APPROVED") return "approved";
1307
+ if (state === "CHANGES_REQUESTED") return "changes-requested";
1308
+ if (state === "DISMISSED") return "dismissed";
1309
+ throw new Error(`Unsupported GitHub review state: ${state}`);
1310
+ }
1311
+ function reviewEventToGithub(event) {
1312
+ if (event === "approve") return "APPROVE";
1313
+ if (event === "request-changes") return "REQUEST_CHANGES";
1314
+ return "COMMENT";
1315
+ }
1316
+ function requirePullRequestNumber(value) {
1317
+ return requirePositiveId(value, "pull request");
1318
+ }
1319
+ function requirePositiveId(value, resource) {
1320
+ const parsed = parsePositiveInteger(value);
1321
+ if (parsed === null) throw new Error(`GitHub ${resource} id must be a positive integer.`);
1322
+ return parsed;
1323
+ }
1324
+ function getGithubInstallationId(connection) {
1325
+ if (connection.type !== "app-installation") throw new Error("GitHub capabilities require an app-installation connection.");
1326
+ return connection.installationId;
1327
+ }
1328
+ function getSingleSourceId(sourceIds, message) {
1329
+ if (sourceIds.length !== 1) throw new Error(message);
1330
+ return sourceIds[0];
1331
+ }
1332
+ function normalizeLabels(labels) {
1333
+ return [...new Set((labels ?? []).map((label) => label.trim()).filter(Boolean))];
1334
+ }
1335
+ function requireSourceId(sourceId, message) {
1336
+ if (!sourceId) throw new Error(message);
1337
+ return sourceId;
1338
+ }
1339
+ function parsePositiveCursor(cursor) {
1340
+ if (cursor === void 0) return 1;
1341
+ const page = parsePositiveInteger(cursor);
1342
+ if (page === null) throw new Error("GitHub cursor must be a positive page number.");
1343
+ return page;
1344
+ }
1345
+ function parsePositiveInteger(value) {
1346
+ if (!/^\d+$/.test(value)) return null;
1347
+ const parsed = Number(value);
1348
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
1349
+ }
1350
+ function isNotFoundError(error) {
1351
+ return typeof error === "object" && error !== null && "status" in error && error.status === 404;
1352
+ }
1353
+ /** Split an `owner/name` full name into its parts, or `null` when malformed. */
1354
+ function splitRepoFullName(repoFullName) {
1355
+ const slash = repoFullName.indexOf("/");
1356
+ if (slash <= 0 || slash === repoFullName.length - 1) return null;
1357
+ return {
1358
+ owner: repoFullName.slice(0, slash),
1359
+ repo: repoFullName.slice(slash + 1)
1360
+ };
1361
+ }
1362
+ function parseGithubExternalTarget(externalId) {
1363
+ const match = externalId.match(/^github:(\d+):(?:issue|pull-request):(\d+)$/) ?? externalId.match(/^(\d+):(\d+)$/);
1364
+ if (!match?.[1] || !match[2]) return null;
1365
+ const repositoryId = parsePositiveInteger(match[1]);
1366
+ const issueId = parsePositiveInteger(match[2]);
1367
+ return repositoryId && issueId ? {
1368
+ repositoryId: String(repositoryId),
1369
+ issueId: String(issueId)
1370
+ } : null;
1371
+ }
1372
+ //#endregion
1373
+ export { GithubIntegration, LIST_PAGE_SIZE, normalizePrivateKey };
1374
+
1375
+ //# sourceMappingURL=integration.js.map