@mastra/factory 0.15.1-alpha.0 → 0.16.0-alpha.11

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 (372) hide show
  1. package/README.md +41 -3
  2. package/dist/auth.js +1 -1
  3. package/dist/auth.js.map +1 -1
  4. package/dist/boards/index.d.ts +1 -1
  5. package/dist/boards/index.d.ts.map +1 -1
  6. package/dist/boards/index.js +2 -2
  7. package/dist/boards/index.js.map +1 -1
  8. package/dist/boards/review.d.ts.map +1 -1
  9. package/dist/boards/review.js +23 -9
  10. package/dist/boards/review.js.map +1 -1
  11. package/dist/boards/semantics.d.ts +7 -0
  12. package/dist/boards/semantics.d.ts.map +1 -1
  13. package/dist/boards/semantics.js +15 -1
  14. package/dist/boards/semantics.js.map +1 -1
  15. package/dist/boards/work.d.ts.map +1 -1
  16. package/dist/boards/work.js +68 -6
  17. package/dist/boards/work.js.map +1 -1
  18. package/dist/capabilities/intake.d.ts +8 -0
  19. package/dist/capabilities/intake.d.ts.map +1 -1
  20. package/dist/capabilities/version-control.d.ts +15 -0
  21. package/dist/capabilities/version-control.d.ts.map +1 -1
  22. package/dist/factory.d.ts +8 -5
  23. package/dist/factory.d.ts.map +1 -1
  24. package/dist/factory.js +136 -53
  25. package/dist/factory.js.map +1 -1
  26. package/dist/integrations/base.d.ts +5 -0
  27. package/dist/integrations/base.d.ts.map +1 -1
  28. package/dist/integrations/github/integration.d.ts.map +1 -1
  29. package/dist/integrations/github/integration.js +21 -0
  30. package/dist/integrations/github/integration.js.map +1 -1
  31. package/dist/integrations/github/routes.js +2 -1
  32. package/dist/integrations/github/routes.js.map +1 -1
  33. package/dist/integrations/github/sandbox.d.ts +41 -42
  34. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  35. package/dist/integrations/github/sandbox.js +416 -227
  36. package/dist/integrations/github/sandbox.js.map +1 -1
  37. package/dist/integrations/github/webhook.d.ts +2 -5
  38. package/dist/integrations/github/webhook.d.ts.map +1 -1
  39. package/dist/integrations/github/webhook.js +8 -48
  40. package/dist/integrations/github/webhook.js.map +1 -1
  41. package/dist/integrations/gitlab/agent-tools.d.ts +14 -0
  42. package/dist/integrations/gitlab/agent-tools.d.ts.map +1 -0
  43. package/dist/integrations/gitlab/agent-tools.js +42 -0
  44. package/dist/integrations/gitlab/agent-tools.js.map +1 -0
  45. package/dist/integrations/gitlab/api.d.ts +222 -0
  46. package/dist/integrations/gitlab/api.d.ts.map +1 -0
  47. package/dist/integrations/gitlab/api.js +274 -0
  48. package/dist/integrations/gitlab/api.js.map +1 -0
  49. package/dist/integrations/gitlab/default-rules.d.ts +125 -0
  50. package/dist/integrations/gitlab/default-rules.d.ts.map +1 -0
  51. package/dist/integrations/gitlab/default-rules.js +172 -0
  52. package/dist/integrations/gitlab/default-rules.js.map +1 -0
  53. package/dist/integrations/gitlab/integration.d.ts +138 -0
  54. package/dist/integrations/gitlab/integration.d.ts.map +1 -0
  55. package/dist/integrations/gitlab/integration.js +705 -0
  56. package/dist/integrations/gitlab/integration.js.map +1 -0
  57. package/dist/integrations/gitlab/issue-reconciler.d.ts +6 -0
  58. package/dist/integrations/gitlab/issue-reconciler.d.ts.map +1 -0
  59. package/dist/integrations/gitlab/issue-reconciler.js +123 -0
  60. package/dist/integrations/gitlab/issue-reconciler.js.map +1 -0
  61. package/dist/integrations/gitlab/merge-request-reconciler.d.ts +6 -0
  62. package/dist/integrations/gitlab/merge-request-reconciler.d.ts.map +1 -0
  63. package/dist/integrations/gitlab/merge-request-reconciler.js +267 -0
  64. package/dist/integrations/gitlab/merge-request-reconciler.js.map +1 -0
  65. package/dist/integrations/gitlab/reconciler.d.ts +5 -0
  66. package/dist/integrations/gitlab/reconciler.d.ts.map +1 -0
  67. package/dist/integrations/gitlab/reconciler.js +31 -0
  68. package/dist/integrations/gitlab/reconciler.js.map +1 -0
  69. package/dist/integrations/gitlab/reconciliation-config.d.ts +3 -0
  70. package/dist/integrations/gitlab/reconciliation-config.d.ts.map +1 -0
  71. package/dist/integrations/gitlab/reconciliation-config.js +17 -0
  72. package/dist/integrations/gitlab/reconciliation-config.js.map +1 -0
  73. package/dist/integrations/gitlab/routes.d.ts +20 -0
  74. package/dist/integrations/gitlab/routes.d.ts.map +1 -0
  75. package/dist/integrations/gitlab/routes.js +473 -0
  76. package/dist/integrations/gitlab/routes.js.map +1 -0
  77. package/dist/integrations/gitlab/rules.d.ts +35 -0
  78. package/dist/integrations/gitlab/rules.d.ts.map +1 -0
  79. package/dist/integrations/gitlab/rules.js +391 -0
  80. package/dist/integrations/gitlab/rules.js.map +1 -0
  81. package/dist/integrations/gitlab/session-subscriptions.d.ts +32 -0
  82. package/dist/integrations/gitlab/session-subscriptions.d.ts.map +1 -0
  83. package/dist/integrations/gitlab/session-subscriptions.js +192 -0
  84. package/dist/integrations/gitlab/session-subscriptions.js.map +1 -0
  85. package/dist/integrations/gitlab/subscriptions.d.ts +70 -0
  86. package/dist/integrations/gitlab/subscriptions.d.ts.map +1 -0
  87. package/dist/integrations/gitlab/subscriptions.js +76 -0
  88. package/dist/integrations/gitlab/subscriptions.js.map +1 -0
  89. package/dist/integrations/gitlab/version-control.d.ts +16 -0
  90. package/dist/integrations/gitlab/version-control.d.ts.map +1 -0
  91. package/dist/integrations/gitlab/version-control.js +622 -0
  92. package/dist/integrations/gitlab/version-control.js.map +1 -0
  93. package/dist/integrations/gitlab/webhook-dispatch.d.ts +75 -0
  94. package/dist/integrations/gitlab/webhook-dispatch.d.ts.map +1 -0
  95. package/dist/integrations/gitlab/webhook-dispatch.js +235 -0
  96. package/dist/integrations/gitlab/webhook-dispatch.js.map +1 -0
  97. package/dist/integrations/gitlab/webhook.d.ts +72 -0
  98. package/dist/integrations/gitlab/webhook.d.ts.map +1 -0
  99. package/dist/integrations/gitlab/webhook.js +201 -0
  100. package/dist/integrations/gitlab/webhook.js.map +1 -0
  101. package/dist/integrations/incidentio/agent-tools.d.ts +49 -0
  102. package/dist/integrations/incidentio/agent-tools.d.ts.map +1 -0
  103. package/dist/integrations/incidentio/agent-tools.js +90 -0
  104. package/dist/integrations/incidentio/agent-tools.js.map +1 -0
  105. package/dist/integrations/incidentio/claim.d.ts +8 -0
  106. package/dist/integrations/incidentio/claim.d.ts.map +1 -0
  107. package/dist/integrations/incidentio/claim.js +14 -0
  108. package/dist/integrations/incidentio/claim.js.map +1 -0
  109. package/dist/integrations/incidentio/default-rules.d.ts +46 -0
  110. package/dist/integrations/incidentio/default-rules.d.ts.map +1 -0
  111. package/dist/integrations/incidentio/default-rules.js +66 -0
  112. package/dist/integrations/incidentio/default-rules.js.map +1 -0
  113. package/dist/integrations/incidentio/integration.d.ts +48 -2
  114. package/dist/integrations/incidentio/integration.d.ts.map +1 -1
  115. package/dist/integrations/incidentio/integration.js +89 -3
  116. package/dist/integrations/incidentio/integration.js.map +1 -1
  117. package/dist/integrations/incidentio/issue-reconciler.d.ts +2 -0
  118. package/dist/integrations/incidentio/issue-reconciler.d.ts.map +1 -1
  119. package/dist/integrations/incidentio/issue-reconciler.js +38 -2
  120. package/dist/integrations/incidentio/issue-reconciler.js.map +1 -1
  121. package/dist/integrations/incidentio/routes.d.ts +71 -0
  122. package/dist/integrations/incidentio/routes.d.ts.map +1 -0
  123. package/dist/integrations/incidentio/routes.js +245 -0
  124. package/dist/integrations/incidentio/routes.js.map +1 -0
  125. package/dist/integrations/incidentio/rules.d.ts +55 -0
  126. package/dist/integrations/incidentio/rules.d.ts.map +1 -0
  127. package/dist/integrations/incidentio/rules.js +175 -0
  128. package/dist/integrations/incidentio/rules.js.map +1 -0
  129. package/dist/integrations/issue-reconciler.d.ts +3 -3
  130. package/dist/integrations/issue-reconciler.d.ts.map +1 -1
  131. package/dist/integrations/issue-reconciler.js +22 -2
  132. package/dist/integrations/issue-reconciler.js.map +1 -1
  133. package/dist/integrations/jira/adf.d.ts +26 -0
  134. package/dist/integrations/jira/adf.d.ts.map +1 -0
  135. package/dist/integrations/jira/adf.js +73 -0
  136. package/dist/integrations/jira/adf.js.map +1 -0
  137. package/dist/integrations/jira/agent-tools.d.ts +45 -0
  138. package/dist/integrations/jira/agent-tools.d.ts.map +1 -0
  139. package/dist/integrations/jira/agent-tools.js +87 -0
  140. package/dist/integrations/jira/agent-tools.js.map +1 -0
  141. package/dist/integrations/jira/api.d.ts +157 -0
  142. package/dist/integrations/jira/api.d.ts.map +1 -0
  143. package/dist/integrations/jira/api.js +141 -0
  144. package/dist/integrations/jira/api.js.map +1 -0
  145. package/dist/integrations/jira/claim.d.ts +9 -0
  146. package/dist/integrations/jira/claim.d.ts.map +1 -0
  147. package/dist/integrations/jira/claim.js +15 -0
  148. package/dist/integrations/jira/claim.js.map +1 -0
  149. package/dist/integrations/jira/default-rules.d.ts +47 -0
  150. package/dist/integrations/jira/default-rules.d.ts.map +1 -0
  151. package/dist/integrations/jira/default-rules.js +67 -0
  152. package/dist/integrations/jira/default-rules.js.map +1 -0
  153. package/dist/integrations/jira/integration.d.ts +114 -0
  154. package/dist/integrations/jira/integration.d.ts.map +1 -0
  155. package/dist/integrations/jira/integration.js +401 -0
  156. package/dist/integrations/jira/integration.js.map +1 -0
  157. package/dist/integrations/jira/issue-reconciler.d.ts +10 -0
  158. package/dist/integrations/jira/issue-reconciler.d.ts.map +1 -0
  159. package/dist/integrations/jira/issue-reconciler.js +70 -0
  160. package/dist/integrations/jira/issue-reconciler.js.map +1 -0
  161. package/dist/integrations/jira/reconciliation-config.d.ts +3 -0
  162. package/dist/integrations/jira/reconciliation-config.d.ts.map +1 -0
  163. package/dist/integrations/jira/reconciliation-config.js +17 -0
  164. package/dist/integrations/jira/reconciliation-config.js.map +1 -0
  165. package/dist/integrations/jira/routes.d.ts +54 -0
  166. package/dist/integrations/jira/routes.d.ts.map +1 -0
  167. package/dist/integrations/jira/routes.js +260 -0
  168. package/dist/integrations/jira/routes.js.map +1 -0
  169. package/dist/integrations/jira/rules.d.ts +57 -0
  170. package/dist/integrations/jira/rules.d.ts.map +1 -0
  171. package/dist/integrations/jira/rules.js +175 -0
  172. package/dist/integrations/jira/rules.js.map +1 -0
  173. package/dist/integrations/linear/claim.d.ts +8 -0
  174. package/dist/integrations/linear/claim.d.ts.map +1 -0
  175. package/dist/integrations/linear/claim.js +14 -0
  176. package/dist/integrations/linear/claim.js.map +1 -0
  177. package/dist/integrations/linear/default-rules.d.ts +1 -0
  178. package/dist/integrations/linear/default-rules.d.ts.map +1 -1
  179. package/dist/integrations/linear/default-rules.js +2 -0
  180. package/dist/integrations/linear/default-rules.js.map +1 -1
  181. package/dist/integrations/linear/integration.d.ts +24 -6
  182. package/dist/integrations/linear/integration.d.ts.map +1 -1
  183. package/dist/integrations/linear/integration.js +257 -37
  184. package/dist/integrations/linear/integration.js.map +1 -1
  185. package/dist/integrations/linear/routes.d.ts +10 -0
  186. package/dist/integrations/linear/routes.d.ts.map +1 -1
  187. package/dist/integrations/linear/routes.js +74 -10
  188. package/dist/integrations/linear/routes.js.map +1 -1
  189. package/dist/integrations/linear/rules.d.ts +1 -1
  190. package/dist/integrations/linear/rules.d.ts.map +1 -1
  191. package/dist/integrations/linear/rules.js +27 -2
  192. package/dist/integrations/linear/rules.js.map +1 -1
  193. package/dist/integrations/platform/connect/routes.d.ts +39 -0
  194. package/dist/integrations/platform/connect/routes.d.ts.map +1 -0
  195. package/dist/integrations/platform/connect/routes.js +129 -0
  196. package/dist/integrations/platform/connect/routes.js.map +1 -0
  197. package/dist/integrations/platform/github/event-worker.js +1 -1
  198. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  199. package/dist/integrations/platform/github/integration.js +22 -1
  200. package/dist/integrations/platform/github/integration.js.map +1 -1
  201. package/dist/integrations/platform/gitlab/event-worker.d.ts +64 -0
  202. package/dist/integrations/platform/gitlab/event-worker.d.ts.map +1 -0
  203. package/dist/integrations/platform/gitlab/event-worker.js +306 -0
  204. package/dist/integrations/platform/gitlab/event-worker.js.map +1 -0
  205. package/dist/integrations/platform/gitlab/integration.d.ts +57 -0
  206. package/dist/integrations/platform/gitlab/integration.d.ts.map +1 -0
  207. package/dist/integrations/platform/gitlab/integration.js +125 -0
  208. package/dist/integrations/platform/gitlab/integration.js.map +1 -0
  209. package/dist/integrations/platform/incidentio/integration.d.ts +61 -4
  210. package/dist/integrations/platform/incidentio/integration.d.ts.map +1 -1
  211. package/dist/integrations/platform/incidentio/integration.js +372 -23
  212. package/dist/integrations/platform/incidentio/integration.js.map +1 -1
  213. package/dist/integrations/platform/jira/agent-tools.d.ts +36 -0
  214. package/dist/integrations/platform/jira/agent-tools.d.ts.map +1 -0
  215. package/dist/integrations/platform/jira/agent-tools.js +85 -0
  216. package/dist/integrations/platform/jira/agent-tools.js.map +1 -0
  217. package/dist/integrations/platform/jira/integration.d.ts +65 -0
  218. package/dist/integrations/platform/jira/integration.d.ts.map +1 -0
  219. package/dist/integrations/platform/jira/integration.js +540 -0
  220. package/dist/integrations/platform/jira/integration.js.map +1 -0
  221. package/dist/integrations/platform/jira/routes.d.ts +55 -0
  222. package/dist/integrations/platform/jira/routes.d.ts.map +1 -0
  223. package/dist/integrations/platform/jira/routes.js +274 -0
  224. package/dist/integrations/platform/jira/routes.js.map +1 -0
  225. package/dist/integrations/platform/linear/integration.d.ts +34 -1
  226. package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
  227. package/dist/integrations/platform/linear/integration.js +271 -48
  228. package/dist/integrations/platform/linear/integration.js.map +1 -1
  229. package/dist/integrations/slack/integration.d.ts.map +1 -1
  230. package/dist/integrations/slack/integration.js +3 -3
  231. package/dist/integrations/slack/integration.js.map +1 -1
  232. package/dist/integrations/slack/slack.d.ts +2 -0
  233. package/dist/integrations/slack/slack.d.ts.map +1 -1
  234. package/dist/integrations/slack/slack.js +21 -7
  235. package/dist/integrations/slack/slack.js.map +1 -1
  236. package/dist/integrations/subscription-session.d.ts +37 -0
  237. package/dist/integrations/subscription-session.d.ts.map +1 -0
  238. package/dist/integrations/subscription-session.js +83 -0
  239. package/dist/integrations/subscription-session.js.map +1 -0
  240. package/dist/packages/_internals/workspace/dist/index.js +1 -11
  241. package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
  242. package/dist/routes/intake.d.ts.map +1 -1
  243. package/dist/routes/intake.js +16 -4
  244. package/dist/routes/intake.js.map +1 -1
  245. package/dist/routes/oauth.js +3 -6
  246. package/dist/routes/oauth.js.map +1 -1
  247. package/dist/routes/projects.d.ts +1 -0
  248. package/dist/routes/projects.d.ts.map +1 -1
  249. package/dist/routes/projects.js +1 -0
  250. package/dist/routes/projects.js.map +1 -1
  251. package/dist/routes/source-control-sessions.d.ts +20 -0
  252. package/dist/routes/source-control-sessions.d.ts.map +1 -0
  253. package/dist/routes/source-control-sessions.js +319 -0
  254. package/dist/routes/source-control-sessions.js.map +1 -0
  255. package/dist/routes/source-control-settings.d.ts +10 -0
  256. package/dist/routes/source-control-settings.d.ts.map +1 -0
  257. package/dist/routes/source-control-settings.js +87 -0
  258. package/dist/routes/source-control-settings.js.map +1 -0
  259. package/dist/routes/surface.d.ts +3 -3
  260. package/dist/routes/surface.d.ts.map +1 -1
  261. package/dist/routes/surface.js +79 -17
  262. package/dist/routes/surface.js.map +1 -1
  263. package/dist/routes/tenant-credentials.d.ts +8 -0
  264. package/dist/routes/tenant-credentials.d.ts.map +1 -1
  265. package/dist/routes/tenant-credentials.js +20 -3
  266. package/dist/routes/tenant-credentials.js.map +1 -1
  267. package/dist/routes/work-items.d.ts.map +1 -1
  268. package/dist/routes/work-items.js +1 -1
  269. package/dist/routes/work-items.js.map +1 -1
  270. package/dist/rules/dispatch-errors.d.ts.map +1 -1
  271. package/dist/rules/dispatch-errors.js +8 -0
  272. package/dist/rules/dispatch-errors.js.map +1 -1
  273. package/dist/rules/dispatcher.d.ts +1 -0
  274. package/dist/rules/dispatcher.d.ts.map +1 -1
  275. package/dist/rules/dispatcher.js +186 -106
  276. package/dist/rules/dispatcher.js.map +1 -1
  277. package/dist/rules/index.d.ts +2 -2
  278. package/dist/rules/index.d.ts.map +1 -1
  279. package/dist/rules/index.js +2 -2
  280. package/dist/rules/start-coordinator.d.ts +1 -1
  281. package/dist/rules/start-coordinator.d.ts.map +1 -1
  282. package/dist/rules/start-coordinator.js +7 -3
  283. package/dist/rules/start-coordinator.js.map +1 -1
  284. package/dist/rules/terminal-cleanup.d.ts +14 -1
  285. package/dist/rules/terminal-cleanup.d.ts.map +1 -1
  286. package/dist/rules/terminal-cleanup.js +20 -0
  287. package/dist/rules/terminal-cleanup.js.map +1 -1
  288. package/dist/rules/tools.d.ts +2 -0
  289. package/dist/rules/tools.d.ts.map +1 -1
  290. package/dist/rules/tools.js +30 -2
  291. package/dist/rules/tools.js.map +1 -1
  292. package/dist/rules/transition-service.d.ts +3 -0
  293. package/dist/rules/transition-service.d.ts.map +1 -1
  294. package/dist/rules/transition-service.js +10 -5
  295. package/dist/rules/transition-service.js.map +1 -1
  296. package/dist/rules/types.d.ts +136 -3
  297. package/dist/rules/types.d.ts.map +1 -1
  298. package/dist/rules/types.js +31 -2
  299. package/dist/rules/types.js.map +1 -1
  300. package/dist/rules/validation.d.ts.map +1 -1
  301. package/dist/rules/validation.js +15 -2
  302. package/dist/rules/validation.js.map +1 -1
  303. package/dist/sandbox/git-ref.d.ts +7 -0
  304. package/dist/sandbox/git-ref.d.ts.map +1 -0
  305. package/dist/sandbox/git-ref.js +15 -0
  306. package/dist/sandbox/git-ref.js.map +1 -0
  307. package/dist/sandbox/session-retirement.js +1 -1
  308. package/dist/sandbox/workdir.d.ts.map +1 -1
  309. package/dist/sandbox/workdir.js +6 -6
  310. package/dist/sandbox/workdir.js.map +1 -1
  311. package/dist/session/factory-session.d.ts +31 -1
  312. package/dist/session/factory-session.d.ts.map +1 -1
  313. package/dist/session/factory-session.js +60 -1
  314. package/dist/session/factory-session.js.map +1 -1
  315. package/dist/session/run-audit.d.ts +9 -0
  316. package/dist/session/run-audit.d.ts.map +1 -1
  317. package/dist/session/run-audit.js +37 -6
  318. package/dist/session/run-audit.js.map +1 -1
  319. package/dist/session/source-control-tools.d.ts +16 -0
  320. package/dist/session/source-control-tools.d.ts.map +1 -0
  321. package/dist/session/source-control-tools.js +464 -0
  322. package/dist/session/source-control-tools.js.map +1 -0
  323. package/dist/skills/service.d.ts +12 -0
  324. package/dist/skills/service.d.ts.map +1 -1
  325. package/dist/skills/service.js +27 -1
  326. package/dist/skills/service.js.map +1 -1
  327. package/dist/storage/domains/intake/base.d.ts +18 -0
  328. package/dist/storage/domains/intake/base.d.ts.map +1 -1
  329. package/dist/storage/domains/intake/base.js +77 -0
  330. package/dist/storage/domains/intake/base.js.map +1 -1
  331. package/dist/storage/domains/work-items/base.d.ts +41 -2
  332. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  333. package/dist/storage/domains/work-items/base.js +159 -12
  334. package/dist/storage/domains/work-items/base.js.map +1 -1
  335. package/dist/supervisor/session-messaging.d.ts +23 -0
  336. package/dist/supervisor/session-messaging.d.ts.map +1 -0
  337. package/dist/supervisor/session-messaging.js +15 -0
  338. package/dist/supervisor/session-messaging.js.map +1 -0
  339. package/dist/supervisor/write-tools.d.ts +2 -1
  340. package/dist/supervisor/write-tools.d.ts.map +1 -1
  341. package/dist/supervisor/write-tools.js +11 -7
  342. package/dist/supervisor/write-tools.js.map +1 -1
  343. package/dist/work-item-branch.d.ts +3 -1
  344. package/dist/work-item-branch.d.ts.map +1 -1
  345. package/dist/work-item-branch.js +26 -6
  346. package/dist/work-item-branch.js.map +1 -1
  347. package/dist/workspace.d.ts +15 -1
  348. package/dist/workspace.d.ts.map +1 -1
  349. package/dist/workspace.js +57 -23
  350. package/dist/workspace.js.map +1 -1
  351. package/factory-skills/factory-gitlab-rereview/SKILL.md +19 -0
  352. package/factory-skills/factory-gitlab-review/SKILL.md +30 -0
  353. package/factory-skills/factory-rereview/SKILL.md +13 -6
  354. package/factory-skills/factory-review/SKILL.md +13 -6
  355. package/factory-skills/factory-review/references/archaeology.md +225 -0
  356. package/factory-skills/factory-review/references/categories/README.md +34 -0
  357. package/factory-skills/factory-review/references/categories/behavior-change.md +36 -0
  358. package/factory-skills/factory-review/references/categories/bug-fix.md +37 -0
  359. package/factory-skills/factory-review/references/categories/docs.md +32 -0
  360. package/factory-skills/factory-review/references/categories/experimental-flagged.md +34 -0
  361. package/factory-skills/factory-review/references/categories/infra-tooling.md +37 -0
  362. package/factory-skills/factory-review/references/categories/internal-capability.md +35 -0
  363. package/factory-skills/factory-review/references/categories/large-cross-cutting.md +35 -0
  364. package/factory-skills/factory-review/references/categories/mechanical.md +36 -0
  365. package/factory-skills/factory-review/references/categories/performance.md +33 -0
  366. package/factory-skills/factory-review/references/categories/public-api.md +38 -0
  367. package/factory-skills/factory-review/references/categories/refactor.md +35 -0
  368. package/factory-skills/factory-review/references/categories/revert.md +31 -0
  369. package/factory-skills/factory-review/references/categories/schema-storage.md +39 -0
  370. package/factory-skills/factory-review/references/categories/security.md +35 -0
  371. package/factory-skills/factory-review/references/categories/tests-only.md +38 -0
  372. package/package.json +12 -12
@@ -0,0 +1,87 @@
1
+ import { registerApiRoute } from "@mastra/core/server";
2
+ //#region src/routes/source-control-settings.ts
3
+ async function loadRepository(c, options) {
4
+ await options.auth.ensureUser(c);
5
+ const tenant = options.auth.tenant(c);
6
+ if (!tenant) return c.json({ error: "unauthorized" }, 401);
7
+ const orgId = tenant.orgId;
8
+ if (!orgId) return c.json({ error: "organization_required" }, 403);
9
+ const id = c.req.param("id");
10
+ if (!id) return c.json({ error: "project_repository_not_found" }, 404);
11
+ const matches = (await Promise.all(options.sourceControls.map(async (sourceControl) => {
12
+ const repository = await sourceControl.projectRepositories.get({
13
+ orgId,
14
+ id
15
+ });
16
+ return repository ? {
17
+ sourceControl,
18
+ repository,
19
+ orgId
20
+ } : null;
21
+ }))).filter((match) => match !== null);
22
+ if (matches.length > 1) return c.json({ error: "ambiguous_project_repository" }, 409);
23
+ return matches[0] ?? c.json({ error: "project_repository_not_found" }, 404);
24
+ }
25
+ function commandFromBody(body, key) {
26
+ const value = body[key];
27
+ if (value === void 0) return void 0;
28
+ if (typeof value === "string") return value.trim() || null;
29
+ return null;
30
+ }
31
+ function buildSourceControlSettingsRoutes(options) {
32
+ const path = "/web/source-control/projects/:id/settings";
33
+ return [registerApiRoute(path, {
34
+ method: "GET",
35
+ requiresAuth: false,
36
+ handler: async (raw) => {
37
+ const c = raw;
38
+ const loaded = await loadRepository(c, options);
39
+ if (loaded instanceof Response) return loaded;
40
+ return c.json({
41
+ setupCommand: loaded.repository.setupCommand,
42
+ teardownCommand: loaded.repository.teardownCommand
43
+ });
44
+ }
45
+ }), registerApiRoute(path, {
46
+ method: "POST",
47
+ requiresAuth: false,
48
+ handler: async (raw) => {
49
+ const c = raw;
50
+ const loaded = await loadRepository(c, options);
51
+ if (loaded instanceof Response) return loaded;
52
+ let body;
53
+ try {
54
+ body = await c.req.json();
55
+ if (!body || typeof body !== "object" || Array.isArray(body)) throw new Error("Invalid JSON body");
56
+ } catch {
57
+ return c.json({ error: "Invalid JSON body" }, 400);
58
+ }
59
+ for (const key of ["setupCommand", "teardownCommand"]) {
60
+ const value = body[key];
61
+ if (value === void 0) continue;
62
+ if (value !== null && typeof value !== "string") return c.json({ error: `Invalid ${key}` }, 400);
63
+ if (typeof value === "string" && value.length > 2e3) return c.json({ error: `${key} too long (max 2000 characters)` }, 400);
64
+ if (typeof value === "string" && /[\0-\x08\x0b\x0c\x0e-\x1f\x7f]/.test(value)) return c.json({ error: `${key} contains control characters` }, 400);
65
+ }
66
+ const setupCommand = commandFromBody(body, "setupCommand");
67
+ const teardownCommand = commandFromBody(body, "teardownCommand");
68
+ const saved = await loaded.sourceControl.projectRepositories.update({
69
+ orgId: loaded.orgId,
70
+ id: loaded.repository.id,
71
+ input: {
72
+ ...setupCommand !== void 0 ? { setupCommand } : {},
73
+ ...teardownCommand !== void 0 ? { teardownCommand } : {}
74
+ }
75
+ });
76
+ if (!saved) return c.json({ error: "project_repository_not_found" }, 404);
77
+ return c.json({
78
+ setupCommand: saved.setupCommand,
79
+ teardownCommand: saved.teardownCommand
80
+ });
81
+ }
82
+ })];
83
+ }
84
+ //#endregion
85
+ export { buildSourceControlSettingsRoutes };
86
+
87
+ //# sourceMappingURL=source-control-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-control-settings.js","names":[],"sources":["../../src/routes/source-control-settings.ts"],"sourcesContent":["import type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\n\nimport type { ProjectRepository, SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { RouteAuth } from './route.js';\n\ninterface SourceControlSettingsRoutesOptions {\n auth: RouteAuth;\n sourceControls: readonly SourceControlStorageHandle[];\n}\n\nasync function loadRepository(\n c: Context,\n options: SourceControlSettingsRoutesOptions,\n): Promise<{ sourceControl: SourceControlStorageHandle; repository: ProjectRepository; orgId: string } | Response> {\n await options.auth.ensureUser(c);\n const tenant = options.auth.tenant(c);\n if (!tenant) return c.json({ error: 'unauthorized' }, 401);\n const orgId = tenant.orgId;\n if (!orgId) return c.json({ error: 'organization_required' }, 403);\n\n const id = c.req.param('id');\n if (!id) return c.json({ error: 'project_repository_not_found' }, 404);\n const matches = (\n await Promise.all(\n options.sourceControls.map(async sourceControl => {\n const repository = await sourceControl.projectRepositories.get({ orgId, id });\n return repository ? { sourceControl, repository, orgId } : null;\n }),\n )\n ).filter(\n (match): match is { sourceControl: SourceControlStorageHandle; repository: ProjectRepository; orgId: string } =>\n match !== null,\n );\n if (matches.length > 1) return c.json({ error: 'ambiguous_project_repository' }, 409);\n return matches[0] ?? c.json({ error: 'project_repository_not_found' }, 404);\n}\n\nfunction commandFromBody(\n body: Record<string, unknown>,\n key: 'setupCommand' | 'teardownCommand',\n): string | null | undefined {\n const value = body[key];\n if (value === undefined) return undefined;\n if (typeof value === 'string') return value.trim() || null;\n return null;\n}\n\nexport function buildSourceControlSettingsRoutes(options: SourceControlSettingsRoutesOptions): ApiRoute[] {\n const path = '/web/source-control/projects/:id/settings';\n return [\n registerApiRoute(path, {\n method: 'GET',\n requiresAuth: false,\n handler: async raw => {\n const c = raw as Context;\n const loaded = await loadRepository(c, options);\n if (loaded instanceof Response) return loaded;\n return c.json({\n setupCommand: loaded.repository.setupCommand,\n teardownCommand: loaded.repository.teardownCommand,\n });\n },\n }),\n registerApiRoute(path, {\n method: 'POST',\n requiresAuth: false,\n handler: async raw => {\n const c = raw as Context;\n const loaded = await loadRepository(c, options);\n if (loaded instanceof Response) return loaded;\n let body: Record<string, unknown>;\n try {\n body = await c.req.json();\n if (!body || typeof body !== 'object' || Array.isArray(body)) throw new Error('Invalid JSON body');\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n\n for (const key of ['setupCommand', 'teardownCommand'] as const) {\n const value = body[key];\n if (value === undefined) continue;\n if (value !== null && typeof value !== 'string') return c.json({ error: `Invalid ${key}` }, 400);\n if (typeof value === 'string' && value.length > 2000)\n return c.json({ error: `${key} too long (max 2000 characters)` }, 400);\n if (typeof value === 'string' && /[\\0-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/.test(value))\n return c.json({ error: `${key} contains control characters` }, 400);\n }\n\n const setupCommand = commandFromBody(body, 'setupCommand');\n const teardownCommand = commandFromBody(body, 'teardownCommand');\n const saved = await loaded.sourceControl.projectRepositories.update({\n orgId: loaded.orgId,\n id: loaded.repository.id,\n input: {\n ...(setupCommand !== undefined ? { setupCommand } : {}),\n ...(teardownCommand !== undefined ? { teardownCommand } : {}),\n },\n });\n if (!saved) return c.json({ error: 'project_repository_not_found' }, 404);\n return c.json({ setupCommand: saved.setupCommand, teardownCommand: saved.teardownCommand });\n },\n }),\n ];\n}\n"],"mappings":"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"}
@@ -25,7 +25,7 @@ import type { MemorySettingsStorage } from '../storage/domains/memory-settings/b
25
25
  import type { ModelPacksStorage } from '../storage/domains/model-packs/base.js';
26
26
  import type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';
27
27
  import type { QueueHealthStorage } from '../storage/domains/queue-health/base.js';
28
- import { type SourceControlStorage } from '../storage/domains/source-control/base.js';
28
+ import { type SourceControlStorage, type SourceControlStorageHandle } from '../storage/domains/source-control/base.js';
29
29
  import { type WorkItemsStorage } from '../storage/domains/work-items/base.js';
30
30
  import type { RouteAuth } from './route.js';
31
31
  export interface IntegrationRegistration {
@@ -91,14 +91,14 @@ export interface FactoryApiRoutesDeps {
91
91
  * browser and no interactive user, so nothing else would catch a regression in
92
92
  * what it forwards.
93
93
  */
94
- export declare function prepareFactoryRuleBinding(github: GithubIntegration, coordinator: Pick<FactoryStartCoordinator, 'prepare'>, projects: FactoryProjectsStorage, boards: BoardRegistry, input: FactoryBindingPreparationInput): Promise<void>;
94
+ export declare function prepareFactoryRuleBinding(sourceControlProvider: SourceControlStorageHandle | Pick<GithubIntegration, 'sourceControlStorage'>, coordinator: Pick<FactoryStartCoordinator, 'prepare'>, projects: FactoryProjectsStorage, boards: BoardRegistry, input: FactoryBindingPreparationInput): Promise<void>;
95
95
  /**
96
96
  * Build the {@link IntegrationContext} handed to an integration when the
97
97
  * factory collects its capabilities (routes, workers). One shape everywhere:
98
98
  * `assembleFactoryApiRoutes` uses it per registration, and `MastraFactory` uses it
99
99
  * when collecting integration workers at finalize.
100
100
  */
101
- export declare function buildIntegrationContext(deps: Pick<FactoryApiRoutesDeps, 'controller' | 'publicOrigin' | 'auth' | 'sandbox' | 'users' | 'factoryStorage' | 'integrationStorage' | 'sourceControlStorage'> & {
101
+ export declare function buildIntegrationContext(deps: Pick<FactoryApiRoutesDeps, 'controller' | 'publicOrigin' | 'auth' | 'sandbox' | 'users' | 'factoryStorage' | 'integrationStorage' | 'sourceControlStorage' | 'integrations'> & {
102
102
  stateSigner: StateSigner;
103
103
  emitAudit?: AuditEmitter['emit'];
104
104
  configVersion: string;
@@ -1 +1 @@
1
- {"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/routes/surface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAQhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACtF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,uCAAuC,CAAC;AAS/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAe5C,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,kBAAkB,CAAC;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAC7C,+FAA+F;IAC/F,YAAY,EAAE,YAAY,CAAC;IAC3B,qEAAqE;IACrE,IAAI,EAAE,SAAS,CAAC;IAChB,kFAAkF;IAClF,KAAK,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;IACpD,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,YAAY,GAAG,aAAa,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qEAAqE;IACrE,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,4EAA4E;IAC5E,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,mFAAmF;IACnF,OAAO,EAAE;QACP,MAAM,EAAE,aAAa,CAAC;QACtB,gBAAgB,EAAE,uBAAuB,CAAC;QAC1C,cAAc,EAAE,qBAAqB,CAAC;QACtC,eAAe,EAAE,sBAAsB,CAAC;QACxC,UAAU,EAAE,iBAAiB,CAAC;QAC9B,UAAU,EAAE,iBAAiB,CAAC;QAC9B,QAAQ,EAAE,sBAAsB,CAAC;QACjC,WAAW,EAAE,kBAAkB,CAAC;QAChC,SAAS,EAAE,gBAAgB,CAAC;QAC5B,eAAe,EAAE,sBAAsB,CAAC;QACxC,QAAQ,EAAE,uBAAuB,CAAC;KACnC,CAAC;IACF,YAAY,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACzC,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,aAAa,EAAE,aAAa,CAAC;IAC7B,oFAAoF;IACpF,IAAI,EAAE,cAAc,CAAC;IACrB,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,kCAAkC,EAAE,4BAA4B,CAAC;IAC5F,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC3B,iBAAiB,EAAE,wBAAwB,CAAC;QAC5C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC3E,KAAK,IAAI,CAAC;CACZ;AAkFD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,iBAAiB,EACzB,WAAW,EAAE,IAAI,CAAC,uBAAuB,EAAE,SAAS,CAAC,EACrD,QAAQ,EAAE,sBAAsB,EAChC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,IAAI,CAAC,CA+Ef;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,CACR,oBAAoB,EAClB,YAAY,GACZ,cAAc,GACd,MAAM,GACN,SAAS,GACT,OAAO,GACP,gBAAgB,GAChB,oBAAoB,GACpB,sBAAsB,CACzB,GAAG;IACF,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,qFAAqF;IACrF,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,IAAI,CACX,oBAAoB,CAAC,SAAS,CAAC,EAC/B,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAC3E,CAAC;IACF;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,EACD,aAAa,EAAE,MAAM,GACpB,kBAAkB,CA4BpB;AA4ED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,oBAAoB,GAAG,QAAQ,EAAE,CAwJ/E"}
1
+ {"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/routes/surface.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,16 @@
1
1
  import { boardForWorkItem } from "../boards/semantics.js";
2
2
  import { workItemBranch, workItemBranchSource, workItemThreadTitle } from "../work-item-branch.js";
3
3
  import "../boards/index.js";
4
- import { MaterializeError } from "../integrations/github/sandbox.js";
5
4
  import { isAgentActor } from "../storage/domains/work-items/base.js";
6
5
  import { getGithubFeatureDiagnostics } from "../integrations/github/config.js";
6
+ import { MaterializeError } from "../integrations/github/sandbox.js";
7
+ import { invalidateTenantCredentialSnapshots } from "./tenant-credentials.js";
7
8
  import { invalidateCustomProvidersSnapshots } from "./custom-provider-source.js";
8
9
  import { FactoryDispatchError } from "../rules/dispatch-errors.js";
9
- import { FactorySourceSessionResolutionError, ensureFactorySourceSession, resolveFactoryDefaultModelId, resolveFactoryProjectForSession } from "../session/factory-session.js";
10
+ import { SourceControlConnectionNotFoundError } from "../storage/domains/source-control/base.js";
11
+ import { FactorySourceSessionResolutionError, createSourceControlSessionLookup, ensureFactorySourceSession, resolveFactoryDefaultModelId, resolveFactoryProjectForSession, resolveFactorySourceControl } from "../session/factory-session.js";
10
12
  import { FactoryStartCoordinator } from "../rules/start-coordinator.js";
11
13
  import { FactoryTransitionService } from "../rules/transition-service.js";
12
- import { SourceControlConnectionNotFoundError } from "../storage/domains/source-control/base.js";
13
14
  import { buildAutomationRunRoutes } from "./automation-runs.js";
14
15
  import { ConfigRoutes } from "./config.js";
15
16
  import { buildFsRoutes } from "./fs.js";
@@ -17,7 +18,8 @@ import { IntakeRoutes } from "./intake.js";
17
18
  import { KnowledgeRoutes } from "./knowledge.js";
18
19
  import { OAuthRoutes } from "./oauth.js";
19
20
  import { SkillRoutes } from "./skills.js";
20
- import { invalidateTenantCredentialSnapshots } from "./tenant-credentials.js";
21
+ import { buildSourceControlSessionRoutes } from "./source-control-sessions.js";
22
+ import { buildSourceControlSettingsRoutes } from "./source-control-settings.js";
21
23
  import { WorkItemRoutes } from "./work-items.js";
22
24
  import { registerApiRoute } from "@mastra/core/server";
23
25
  //#region src/routes/surface.ts
@@ -102,8 +104,9 @@ async function reuseBoundSession(sourceControl, input) {
102
104
  * browser and no interactive user, so nothing else would catch a regression in
103
105
  * what it forwards.
104
106
  */
105
- async function prepareFactoryRuleBinding(github, coordinator, projects, boards, input) {
107
+ async function prepareFactoryRuleBinding(sourceControlProvider, coordinator, projects, boards, input) {
106
108
  try {
109
+ const sourceControl = "sourceControlStorage" in sourceControlProvider ? sourceControlProvider.sourceControlStorage : sourceControlProvider;
107
110
  const source = workItemBranchSource(input.item.externalSource);
108
111
  const branch = workItemBranch({
109
112
  id: input.item.id,
@@ -117,8 +120,8 @@ async function prepareFactoryRuleBinding(github, coordinator, projects, boards,
117
120
  if (!destinationStage) throw new FactoryDispatchError("unsupported_provider_item", `Factory skill invocation has no destination lane (role "${input.role}", stages [${input.item.stages.join(", ")}]).`);
118
121
  const repositorySlug = typeof input.item.metadata?.repository === "string" ? input.item.metadata.repository : void 0;
119
122
  const approver = input.record.approvedBy ?? void 0;
120
- const preparedSession = await reuseBoundSession(github.sourceControlStorage, input) ?? await ensureFactorySourceSession({
121
- sourceControl: github.sourceControlStorage,
123
+ const preparedSession = await reuseBoundSession(sourceControl, input) ?? await ensureFactorySourceSession({
124
+ sourceControl,
122
125
  orgId: input.record.orgId,
123
126
  factoryProjectId: input.record.factoryProjectId,
124
127
  repositorySlug,
@@ -178,6 +181,7 @@ function buildIntegrationContext(deps, integrationId) {
178
181
  generic: deps.integrationStorage.forIntegration(integrationId),
179
182
  sourceControl: deps.sourceControlStorage.forIntegration(integrationId),
180
183
  ...deps.sourceControlOwnerId ? { sourceControlOwner: deps.sourceControlStorage.forIntegration(deps.sourceControlOwnerId) } : {},
184
+ sourceControls: (deps.integrations ?? []).filter(({ integration }) => integration.versionControl).map(({ integration }) => deps.sourceControlStorage.forIntegration(integration.id)),
181
185
  projects: deps.domains.projects,
182
186
  intake: deps.domains.intake,
183
187
  channelIdentity: deps.domains.channelIdentity,
@@ -197,9 +201,10 @@ function buildIntegrationContext(deps, integrationId) {
197
201
  }
198
202
  /**
199
203
  * Disabled-status stub for the well-known integration ids. The SPA polls
200
- * `/web/github/status` and `/web/linear/status` unconditionally, so when an
201
- * integration is absent (or not ready) the status contract must still hold.
202
- * Unknown custom ids get no stub — the SPA doesn't poll them.
204
+ * `/web/github/status`, `/web/linear/status`, and `/web/jira/status`
205
+ * unconditionally, so when an integration is absent (or not ready) the status
206
+ * contract must still hold. Unknown custom ids get no stub — the SPA doesn't
207
+ * poll them.
203
208
  */
204
209
  function disabledIntegrationStatusRoutes(deps, id, configured = false) {
205
210
  if (id === "github") return [registerApiRoute("/web/github/status", {
@@ -234,6 +239,21 @@ function disabledIntegrationStatusRoutes(deps, id, configured = false) {
234
239
  }
235
240
  })
236
241
  })];
242
+ if (id === "jira") return [registerApiRoute("/web/jira/status", {
243
+ method: "GET",
244
+ requiresAuth: false,
245
+ handler: (c) => c.json({
246
+ enabled: false,
247
+ configured,
248
+ site: null,
249
+ reason: "missing_config",
250
+ diagnostics: {
251
+ jiraConfigured: configured,
252
+ factoryAuthEnabled: deps.auth.enabled(),
253
+ appDbConfigured: deps.factoryStorage !== void 0
254
+ }
255
+ })
256
+ })];
237
257
  return [];
238
258
  }
239
259
  /**
@@ -271,7 +291,10 @@ function assembleFactoryApiRoutes(deps) {
271
291
  const registrations = deps.integrations ?? [];
272
292
  const githubRegistration = registrations.find(({ integration }) => integration.id === "github");
273
293
  const githubStorage = githubRegistration ? deps.sourceControlStorage.forIntegration("github") : void 0;
274
- const githubIntegration = githubRegistration?.integration;
294
+ githubRegistration?.integration;
295
+ const sourceControlRegistrations = registrations.filter(({ integration }) => integration.versionControl);
296
+ const sourceControls = [.../* @__PURE__ */ new Set(["github", ...sourceControlRegistrations.map(({ integration }) => integration.id)])].map((id) => deps.sourceControlStorage.forIntegration(id));
297
+ const sourceControlSessions = createSourceControlSessionLookup(sourceControls);
275
298
  const integrationRoutes = registrations.flatMap((registration) => {
276
299
  const { integration } = registration;
277
300
  if (!deps.stateSigner) return disabledIntegrationStatusRoutes(deps, integration.id, true);
@@ -286,7 +309,28 @@ function assembleFactoryApiRoutes(deps) {
286
309
  routes: integration.routes(context)
287
310
  });
288
311
  });
289
- const absentStubs = ["github", "linear"].filter((id) => !registrations.some(({ integration }) => integration.id === id)).flatMap((id) => disabledIntegrationStatusRoutes(deps, id));
312
+ const sharedSessionRouteKeys = /* @__PURE__ */ new Set([
313
+ "GET /web/github/projects/:id/sessions",
314
+ "POST /web/github/projects/:id/sessions",
315
+ "GET /web/user-sessions/:sessionId",
316
+ "DELETE /web/user-sessions/:sessionId",
317
+ "POST /web/user-sessions/:sessionId/title"
318
+ ]);
319
+ const providerRoutes = integrationRoutes.filter((route) => !sharedSessionRouteKeys.has(route.method + " " + route.path));
320
+ const sourceControlSessionRoutes = sourceControls.length === 0 ? [] : buildSourceControlSessionRoutes({
321
+ auth: deps.auth,
322
+ sourceControls,
323
+ ...deps.users ? { users: deps.users } : {},
324
+ controller: deps.controller,
325
+ memorySettings: deps.domains.memorySettings,
326
+ sessionRetirement: deps.sessionRetirement,
327
+ ...deps.factoryReady ? { workItems: deps.domains.workItems } : {}
328
+ });
329
+ const absentStubs = [
330
+ "github",
331
+ "linear",
332
+ "jira"
333
+ ].filter((id) => !registrations.some(({ integration }) => integration.id === id)).flatMap((id) => disabledIntegrationStatusRoutes(deps, id));
290
334
  const slackAbsentStubs = registrations.some(({ integration }) => integration.id === "slack") ? [] : absentSlackChannelAccountsRoutes();
291
335
  const transitionService = deps.factoryReady ? deps.factoryTransitionService ?? new FactoryTransitionService({
292
336
  configVersion: deps.configVersion,
@@ -294,17 +338,30 @@ function assembleFactoryApiRoutes(deps) {
294
338
  storage: deps.domains.workItems,
295
339
  audit: deps.audit
296
340
  }) : void 0;
297
- const startCoordinator = transitionService ? new FactoryStartCoordinator(deps.controller, deps.domains.workItems, transitionService, githubIntegration?.sourceControlStorage, deps.domains.memorySettings) : void 0;
341
+ const startCoordinator = transitionService ? new FactoryStartCoordinator(deps.controller, deps.domains.workItems, transitionService, (request) => resolveFactorySourceControl({
342
+ sourceControls,
343
+ orgId: request.orgId,
344
+ factoryProjectId: request.factoryProjectId,
345
+ sessionId: request.sessionId
346
+ }), deps.domains.memorySettings) : void 0;
298
347
  if (transitionService && startCoordinator) deps.onFactoryRuntime?.({
299
348
  transitionService,
300
- ...githubIntegration ? { prepareBinding: (input) => prepareFactoryRuleBinding(githubIntegration, startCoordinator, deps.domains.projects, deps.boardRegistry, input) } : {}
349
+ ...sourceControlRegistrations.length > 0 ? { prepareBinding: async (input) => {
350
+ const sourceControl = await resolveFactorySourceControl({
351
+ sourceControls,
352
+ orgId: input.record.orgId,
353
+ factoryProjectId: input.record.factoryProjectId
354
+ });
355
+ if (!sourceControl) throw new FactoryDispatchError("source_control_missing", "Factory project has no linked source-control repository.");
356
+ return prepareFactoryRuleBinding(sourceControl, startCoordinator, deps.domains.projects, deps.boardRegistry, input);
357
+ } } : {}
301
358
  });
302
359
  return [
303
360
  ...buildFsRoutes({
304
361
  root: deps.fsRoot,
305
362
  sessionFs: {
306
363
  auth: deps.auth,
307
- sessions: deps.sourceControlStorage.forIntegration("github").sessions,
364
+ sessions: sourceControlSessions,
308
365
  filesystem: deps.domains.filesystem
309
366
  }
310
367
  }),
@@ -314,7 +371,7 @@ function assembleFactoryApiRoutes(deps) {
314
371
  authStorage: deps.authStorage,
315
372
  modelCredentials: deps.domains.modelCredentials,
316
373
  modelPacks: deps.domains.modelPacks,
317
- sourceControlSessions: deps.sourceControlStorage.forIntegration("github").sessions,
374
+ sourceControlSessions,
318
375
  memorySettings: deps.domains.memorySettings,
319
376
  factoryProjects: deps.domains.projects,
320
377
  customProviders: deps.domains.customProviders,
@@ -336,7 +393,12 @@ function assembleFactoryApiRoutes(deps) {
336
393
  sourceControlStorage: githubStorage,
337
394
  ensureSourceControlReady: githubRegistration?.ensureReady
338
395
  }).routes(),
339
- ...integrationRoutes,
396
+ ...sourceControlSessionRoutes,
397
+ ...sourceControls.length === 0 ? [] : buildSourceControlSettingsRoutes({
398
+ auth: deps.auth,
399
+ sourceControls
400
+ }),
401
+ ...providerRoutes,
340
402
  ...absentStubs,
341
403
  ...slackAbsentStubs,
342
404
  ...deps.intakeReady ? new IntakeRoutes({
@@ -1 +1 @@
1
- {"version":3,"file":"surface.js","names":[],"sources":["../../src/routes/surface.ts"],"sourcesContent":["import type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentController } from '@mastra/core/agent-controller';\nimport type { ApiRoute, IUserProvider } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { FactoryStorage } from '@mastra/core/storage';\n\nimport { boardForWorkItem } from '../boards/index.js';\nimport type { BoardRegistry } from '../boards/index.js';\nimport type { FactoryIntegration, IntegrationContext } from '../integrations/base.js';\nimport { getGithubFeatureDiagnostics } from '../integrations/github/config.js';\nimport type { GithubIntegration } from '../integrations/github/integration.js';\nimport { MaterializeError } from '../integrations/github/sandbox.js';\nimport { FactoryDispatchError } from '../rules/dispatch-errors.js';\nimport type { FactoryBindingPreparationInput } from '../rules/dispatcher.js';\nimport { FactoryStartCoordinator } from '../rules/start-coordinator.js';\nimport { FactoryTransitionService } from '../rules/transition-service.js';\nimport type { MastraFactorySandboxConfig } from '../sandbox/session-sandbox.js';\nimport {\n ensureFactorySourceSession,\n FactorySourceSessionResolutionError,\n resolveFactoryDefaultModelId,\n resolveFactoryProjectForSession,\n} from '../session/factory-session.js';\nimport type { EnsuredFactorySourceSession } from '../session/factory-session.js';\nimport type { LiveSessions } from '../session/live-sessions.js';\nimport type { StateSigner } from '../state-signing.js';\nimport type { AuditEmitter, AuditRecorder } from '../storage/domains/audit/domain.js';\nimport type { ChannelIdentityStorage } from '../storage/domains/channel-identity/base.js';\nimport type { WorkItemCommentsStorage } from '../storage/domains/comments/base.js';\nimport type { CommentsDomain } from '../storage/domains/comments/domain.js';\nimport type { ModelCredentialsStorage } from '../storage/domains/credentials/base.js';\nimport type { CustomProvidersStorage } from '../storage/domains/custom-providers/base.js';\nimport type { FilesystemStorage } from '../storage/domains/filesystem/base.js';\nimport type { IntakeStorage } from '../storage/domains/intake/base.js';\nimport type { IntegrationStorage } from '../storage/domains/integrations/base.js';\nimport type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';\nimport type { ModelPacksStorage } from '../storage/domains/model-packs/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type { QueueHealthStorage } from '../storage/domains/queue-health/base.js';\nimport {\n SourceControlConnectionNotFoundError,\n type SourceControlStorage,\n} from '../storage/domains/source-control/base.js';\nimport {\n isAgentActor,\n type FactoryDispatchFailureCode,\n type WorkItemsStorage,\n} from '../storage/domains/work-items/base.js';\nimport { workItemBranch, workItemBranchSource, workItemThreadTitle } from '../work-item-branch.js';\nimport { buildAutomationRunRoutes } from './automation-runs.js';\nimport { ConfigRoutes } from './config.js';\nimport { invalidateCustomProvidersSnapshots } from './custom-provider-source.js';\nimport { buildFsRoutes } from './fs.js';\nimport { IntakeRoutes } from './intake.js';\nimport { KnowledgeRoutes } from './knowledge.js';\nimport { OAuthRoutes } from './oauth.js';\nimport type { RouteAuth } from './route.js';\nimport { SkillRoutes } from './skills.js';\nimport { invalidateTenantCredentialSnapshots } from './tenant-credentials.js';\nimport { WorkItemRoutes } from './work-items.js';\n\nconst MATERIALIZE_FAILURE_CODE = {\n 'git-missing': 'repository_git_missing',\n 'egress-blocked': 'repository_egress_blocked',\n 'clone-failed': 'repository_clone_failed',\n 'pull-failed': 'repository_pull_failed',\n 'push-failed': 'repository_push_failed',\n 'commit-failed': 'repository_commit_failed',\n 'gh-missing': 'repository_cli_missing',\n 'pr-failed': 'repository_pr_failed',\n} satisfies Record<MaterializeError['code'], FactoryDispatchFailureCode>;\nexport interface IntegrationRegistration {\n integration: FactoryIntegration;\n ready: boolean;\n ensureReady: () => Promise<void>;\n}\n\nexport interface FactoryApiRoutesDeps {\n controllerId: string;\n controller: AgentController<MastraCodeState>;\n /** Registry of the sessions this process holds, owned by the host so it can watch them too. */\n liveSessions: LiveSessions;\n /** Request-auth seam threaded from the host (no service locator). */\n auth: RouteAuth;\n /** Optional user directory for resolving persisted owners to display profiles. */\n users?: Pick<IUserProvider, 'getUser' | 'getUsers'>;\n authStorage: AuthStorage;\n audit: AuditEmitter & AuditRecorder;\n fsRoot?: string;\n publicOrigin: string;\n stateSigner?: StateSigner;\n /** Sandbox surface (enablement, provider label, create callback). */\n sandbox?: MastraFactorySandboxConfig;\n /** Root factory storage backend (distributed locks, app-db diagnostics). */\n factoryStorage?: FactoryStorage;\n integrationStorage: IntegrationStorage;\n sourceControlStorage: SourceControlStorage;\n /** App-table domain handles, registered and owned by `MastraFactory.prepare()`. */\n domains: {\n intake: IntakeStorage;\n modelCredentials: ModelCredentialsStorage;\n memorySettings: MemorySettingsStorage;\n customProviders: CustomProvidersStorage;\n filesystem: FilesystemStorage;\n modelPacks: ModelPacksStorage;\n projects: FactoryProjectsStorage;\n queueHealth: QueueHealthStorage;\n workItems: WorkItemsStorage;\n channelIdentity: ChannelIdentityStorage;\n comments: WorkItemCommentsStorage;\n };\n integrations?: IntegrationRegistration[];\n intakeReady: boolean;\n factoryReady: boolean;\n knowledgeEnabled: boolean;\n /** Resolved Factory rule set, threaded from the host (no service locator). */\n configVersion: string;\n /** Boards installed for this Factory instance. */\n boardRegistry: BoardRegistry;\n /** Work-item feed service, handed to integrations that ingest platform messages. */\n feed: CommentsDomain;\n factoryTransitionService?: FactoryTransitionService;\n sessionRetirement?: import('../sandbox/session-retirement.js').SessionRetirementCoordinator;\n onFactoryRuntime?: (runtime: {\n transitionService: FactoryTransitionService;\n prepareBinding?: (input: FactoryBindingPreparationInput) => Promise<void>;\n }) => void;\n}\n\nfunction guardIntegrationRoutes({\n integration,\n ready,\n ensureReady,\n routes,\n}: IntegrationRegistration & { routes: ApiRoute[] }): ApiRoute[] {\n if (ready) return routes;\n return routes.map(route => {\n if ('handler' in route) {\n const handler = route.handler;\n return {\n ...route,\n handler: async (context: Parameters<typeof handler>[0]) => {\n try {\n await ensureReady();\n } catch {\n return context.json(\n { error: 'integration_unavailable', message: `${integration.id} integration is unavailable.` },\n 503,\n );\n }\n return handler(context, async () => {});\n },\n };\n }\n\n const createHandler = route.createHandler;\n return {\n ...route,\n createHandler: async (args: Parameters<typeof createHandler>[0]) => {\n const handler = await createHandler(args);\n return async (context: Parameters<typeof handler>[0]) => {\n try {\n await ensureReady();\n } catch {\n return context.json(\n { error: 'integration_unavailable', message: `${integration.id} integration is unavailable.` },\n 503,\n );\n }\n return handler(context);\n };\n },\n };\n });\n}\n\n/**\n * Resolve the source-control session the work item already holds for this role,\n * when it still resolves to the item's org and factory project. Returns\n * `undefined` when there is no ref or the ref no longer resolves, so the caller\n * falls back to minting one.\n */\nasync function reuseBoundSession(\n sourceControl: GithubIntegration['sourceControlStorage'],\n input: FactoryBindingPreparationInput,\n): Promise<EnsuredFactorySourceSession | undefined> {\n const ref = input.item.sessions[input.role];\n if (!ref) return undefined;\n // At least as strict as the coordinator's resolveSourceSession: a ref it\n // would reject must fall through to minting, not hard-fail the run.\n const resolved = await resolveFactoryProjectForSession({ sourceControl, sessionId: ref.sessionId });\n if (\n !resolved ||\n resolved.orgId !== input.record.orgId ||\n resolved.factoryProjectId !== input.record.factoryProjectId\n ) {\n return undefined;\n }\n const session = await sourceControl.sessions.getBySessionId(ref.sessionId);\n if (!session) return undefined;\n return {\n sessionId: session.sessionId,\n userId: session.userId,\n projectRepositoryId: session.projectRepositoryId,\n branch: session.branch,\n baseBranch: session.baseBranch,\n };\n}\n\n/**\n * Start a factory run for a rule binding: ensure the source-control session the\n * coordinator requires, then hand it to `prepare` along with the factory's\n * default model. Exported for tests — this is the autonomous entry point with no\n * browser and no interactive user, so nothing else would catch a regression in\n * what it forwards.\n */\nexport async function prepareFactoryRuleBinding(\n github: GithubIntegration,\n coordinator: Pick<FactoryStartCoordinator, 'prepare'>,\n projects: FactoryProjectsStorage,\n boards: BoardRegistry,\n input: FactoryBindingPreparationInput,\n): Promise<void> {\n try {\n const source = workItemBranchSource(input.item.externalSource);\n const branch = workItemBranch({ id: input.item.id, source, metadata: input.item.metadata });\n // Only leaving a resting phase derives a lane from the role: roles don't own lanes,\n // and the Done close-out running in the triage seat must not drag the card back.\n // Both the current phase and the role's lane come from the installed board; an\n // unknown board or phase yields no destination rather than a guessed one.\n const board = boards.get(boardForWorkItem(input.item));\n const currentStage = input.item.stages.length === 1 ? input.item.stages[0] : undefined;\n const currentKind = currentStage === undefined ? undefined : board?.phaseKind(currentStage);\n const destinationStage =\n currentKind === undefined\n ? undefined\n : currentKind === 'resting'\n ? board?.phaseForRole(input.role)\n : currentStage;\n if (!destinationStage) {\n throw new FactoryDispatchError(\n 'unsupported_provider_item',\n `Factory skill invocation has no destination lane (role \"${input.role}\", stages [${input.item.stages.join(', ')}]).`,\n );\n }\n const repositorySlug =\n typeof input.item.metadata?.repository === 'string' ? input.item.metadata.repository : undefined;\n // Re-preparing a binding (server restart, retired controller session) must\n // land in the role's existing session: minting a replacement would repoint\n // the work item, flip the session's owner to the approver, and orphan the\n // previous sandbox.\n const approver = input.record.approvedBy ?? undefined;\n const preparedSession =\n (await reuseBoundSession(github.sourceControlStorage, input)) ??\n (await ensureFactorySourceSession({\n sourceControl: github.sourceControlStorage,\n orgId: input.record.orgId,\n factoryProjectId: input.record.factoryProjectId,\n repositorySlug,\n branch,\n // A person who approved the run is its interactive user: attribute it to\n // them, not the repo connector. An agent's pre-approval names no person.\n attributeToUserId: isAgentActor(approver) ? undefined : approver,\n }));\n\n await coordinator.prepare({\n orgId: input.record.orgId,\n userId: preparedSession.userId,\n factoryProjectId: input.record.factoryProjectId,\n sessionId: preparedSession.sessionId,\n defaultModelId: await resolveFactoryDefaultModelId(projects, input.record.factoryProjectId),\n threadTitle: workItemThreadTitle({ source, title: input.item.title, metadata: input.item.metadata }),\n kickoffKey: input.record.id,\n destinationStage,\n workItem: {\n id: input.item.id,\n role: input.role,\n input: {\n externalSource: input.item.externalSource,\n parentWorkItemId: input.item.parentWorkItemId,\n title: input.item.title,\n stages: ['intake'],\n sessions: input.item.sessions,\n metadata: input.item.metadata,\n },\n },\n });\n } catch (error) {\n if (error instanceof FactoryDispatchError) throw error;\n if (error instanceof FactorySourceSessionResolutionError) {\n const code = error.reason === 'connection' ? 'source_control_missing' : 'source_repository_missing';\n throw new FactoryDispatchError(code, error.message, { cause: error });\n }\n if (error instanceof SourceControlConnectionNotFoundError) {\n throw new FactoryDispatchError('source_control_missing', error.message, { cause: error });\n }\n if (error instanceof MaterializeError) {\n throw new FactoryDispatchError(MATERIALIZE_FAILURE_CODE[error.code], error.message, { cause: error });\n }\n throw error;\n }\n}\n\n/**\n * Build the {@link IntegrationContext} handed to an integration when the\n * factory collects its capabilities (routes, workers). One shape everywhere:\n * `assembleFactoryApiRoutes` uses it per registration, and `MastraFactory` uses it\n * when collecting integration workers at finalize.\n */\nexport function buildIntegrationContext(\n deps: Pick<\n FactoryApiRoutesDeps,\n | 'controller'\n | 'publicOrigin'\n | 'auth'\n | 'sandbox'\n | 'users'\n | 'factoryStorage'\n | 'integrationStorage'\n | 'sourceControlStorage'\n > & {\n stateSigner: StateSigner;\n emitAudit?: AuditEmitter['emit'];\n configVersion: string;\n boardRegistry: BoardRegistry;\n factoryReady: boolean;\n /** Work-item feed service, so a channel integration can ingest platform messages. */\n feed: CommentsDomain;\n domains: Pick<\n FactoryApiRoutesDeps['domains'],\n 'projects' | 'intake' | 'workItems' | 'channelIdentity' | 'memorySettings'\n >;\n /**\n * Stable id of the registered source-control-owning integration (today:\n * `'github'` when registered). Every call site must derive and pass it so\n * `routes()`, `channels()`, and `workers()` all see the same context shape.\n */\n sourceControlOwnerId?: string;\n },\n integrationId: string,\n): IntegrationContext {\n return {\n auth: deps.auth,\n sandbox: deps.sandbox,\n ...(deps.users ? { users: deps.users } : {}),\n factoryStorage: deps.factoryStorage,\n baseUrl: deps.publicOrigin,\n controller: deps.controller,\n stateSigner: deps.stateSigner,\n storage: {\n generic: deps.integrationStorage.forIntegration(integrationId),\n sourceControl: deps.sourceControlStorage.forIntegration(integrationId),\n ...(deps.sourceControlOwnerId\n ? { sourceControlOwner: deps.sourceControlStorage.forIntegration(deps.sourceControlOwnerId) }\n : {}),\n projects: deps.domains.projects,\n intake: deps.domains.intake,\n channelIdentity: deps.domains.channelIdentity,\n memorySettings: deps.domains.memorySettings,\n },\n ...(deps.factoryReady ? { workItems: deps.domains.workItems, feed: deps.feed } : {}),\n ...(deps.factoryReady\n ? {\n runtime: { configVersion: deps.configVersion, workItems: deps.domains.workItems, boards: deps.boardRegistry },\n }\n : {}),\n ...(deps.emitAudit ? { hooks: { emitAudit: deps.emitAudit } } : {}),\n };\n}\n\n/**\n * Disabled-status stub for the well-known integration ids. The SPA polls\n * `/web/github/status` and `/web/linear/status` unconditionally, so when an\n * integration is absent (or not ready) the status contract must still hold.\n * Unknown custom ids get no stub — the SPA doesn't poll them.\n */\nfunction disabledIntegrationStatusRoutes(deps: FactoryApiRoutesDeps, id: string, configured = false): ApiRoute[] {\n if (id === 'github') {\n return [\n registerApiRoute('/web/github/status', {\n method: 'GET',\n requiresAuth: false,\n handler: c =>\n c.json({\n enabled: false,\n connected: false,\n installations: [],\n reason: 'missing_config',\n diagnostics: getGithubFeatureDiagnostics({\n github: undefined,\n auth: deps.auth,\n appDbConfigured: deps.factoryStorage !== undefined,\n stateSigner: deps.stateSigner,\n sandbox: deps.sandbox,\n }),\n }),\n }),\n ];\n }\n if (id === 'linear') {\n return [\n registerApiRoute('/web/linear/status', {\n method: 'GET',\n requiresAuth: false,\n handler: c =>\n c.json({\n enabled: false,\n connected: false,\n workspace: null,\n reason: 'missing_config',\n diagnostics: {\n linearAppConfigured: configured,\n factoryAuthEnabled: deps.auth.enabled(),\n appDbConfigured: true,\n },\n }),\n }),\n ];\n }\n return [];\n}\n\n/**\n * Stub for `GET /web/channel-accounts` when NO Slack integration is\n * registered. The SPA's Connections section polls the path unconditionally;\n * without a stub the SPA fallback serves HTML, which the UI can only read as\n * \"old server / unknown\". The machine-readable reason lets it say the truth:\n * the integration isn't registered.\n *\n * Mounted only for ABSENT slack — a registered integration owns the path via\n * its connect routes (or, when the state signer is unstable, gets no routes\n * at all and the UI falls back to the generic copy). Static payload, leaks\n * nothing → no auth needed, same posture as the github/linear stubs.\n */\nfunction absentSlackChannelAccountsRoutes(): ApiRoute[] {\n return [\n registerApiRoute('/web/channel-accounts', {\n method: 'GET',\n requiresAuth: false,\n handler: c => c.json({ accounts: [], canConnect: false, reason: 'not_registered' }),\n }),\n ];\n}\n\n/**\n * Assemble the custom `/web/*` API routes as Mastra `server.apiRoutes`:\n * - fs browser routes (project picker), confined to `fsRoot`\n * - config routes (provider/API-key/model-pack/OM management)\n * - every registered integration's `routes()` surface (full set when ready,\n * disabled-status stub otherwise), plus stubs for absent known ids\n */\nexport function assembleFactoryApiRoutes(deps: FactoryApiRoutesDeps): ApiRoute[] {\n const emitAudit: AuditEmitter['emit'] = args => deps.audit.emit(args);\n const registrations = deps.integrations ?? [];\n const githubRegistration = registrations.find(({ integration }) => integration.id === 'github');\n const githubStorage = githubRegistration ? deps.sourceControlStorage.forIntegration('github') : undefined;\n const githubIntegration = githubRegistration?.integration as GithubIntegration | undefined;\n\n const integrationRoutes = registrations.flatMap(registration => {\n const { integration } = registration;\n if (!deps.stateSigner) return disabledIntegrationStatusRoutes(deps, integration.id, true);\n const context = buildIntegrationContext(\n {\n ...deps,\n stateSigner: deps.stateSigner,\n emitAudit,\n ...(githubRegistration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n );\n return guardIntegrationRoutes({ ...registration, routes: integration.routes(context) });\n });\n // Absent known integrations still get their disabled-status stub.\n const absentStubs = ['github', 'linear']\n .filter(id => !registrations.some(({ integration }) => integration.id === id))\n .flatMap(id => disabledIntegrationStatusRoutes(deps, id));\n // Absent slack gets the channel-accounts not-registered stub (registered\n // slack owns the path via its own connect routes).\n const slackAbsentStubs = registrations.some(({ integration }) => integration.id === 'slack')\n ? []\n : absentSlackChannelAccountsRoutes();\n\n const transitionService = deps.factoryReady\n ? (deps.factoryTransitionService ??\n new FactoryTransitionService({\n configVersion: deps.configVersion,\n boards: deps.boardRegistry,\n storage: deps.domains.workItems,\n audit: deps.audit,\n }))\n : undefined;\n const startCoordinator = transitionService\n ? new FactoryStartCoordinator(\n deps.controller,\n deps.domains.workItems,\n transitionService,\n githubIntegration?.sourceControlStorage,\n deps.domains.memorySettings,\n )\n : undefined;\n if (transitionService && startCoordinator) {\n deps.onFactoryRuntime?.({\n transitionService,\n ...(githubIntegration\n ? {\n prepareBinding: (input: FactoryBindingPreparationInput) =>\n prepareFactoryRuleBinding(\n githubIntegration,\n startCoordinator,\n deps.domains.projects,\n deps.boardRegistry,\n input,\n ),\n }\n : {}),\n });\n }\n\n return [\n ...buildFsRoutes({\n root: deps.fsRoot,\n sessionFs: {\n auth: deps.auth,\n sessions: deps.sourceControlStorage.forIntegration('github').sessions,\n filesystem: deps.domains.filesystem,\n },\n }),\n ...new ConfigRoutes({\n auth: deps.auth,\n controller: deps.controller,\n authStorage: deps.authStorage,\n modelCredentials: deps.domains.modelCredentials,\n modelPacks: deps.domains.modelPacks,\n sourceControlSessions: deps.sourceControlStorage.forIntegration('github').sessions,\n memorySettings: deps.domains.memorySettings,\n factoryProjects: deps.domains.projects,\n customProviders: deps.domains.customProviders,\n features: { knowledge: deps.knowledgeEnabled },\n onCredentialsChanged: invalidateTenantCredentialSnapshots,\n onCustomProvidersChanged: invalidateCustomProvidersSnapshots,\n }).routes(),\n ...new OAuthRoutes({\n auth: deps.auth,\n authStorage: deps.authStorage,\n modelCredentials: deps.domains.modelCredentials,\n memorySettings: deps.domains.memorySettings,\n onCredentialsChanged: invalidateTenantCredentialSnapshots,\n }).routes(),\n ...new SkillRoutes({\n auth: deps.auth,\n controllerId: deps.controllerId,\n controller: deps.controller,\n sourceControlStorage: githubStorage,\n ensureSourceControlReady: githubRegistration?.ensureReady,\n }).routes(),\n ...integrationRoutes,\n ...absentStubs,\n ...slackAbsentStubs,\n ...(deps.intakeReady\n ? new IntakeRoutes({\n auth: deps.auth,\n audit: deps.audit,\n intake: deps.domains.intake,\n projects: deps.domains.projects,\n boardRegistry: deps.boardRegistry,\n // Relocation reads and writes work items, which init fail-soft separately from intake.\n ...(deps.factoryReady ? { workItems: deps.domains.workItems } : {}),\n integrations: (deps.integrations ?? []).flatMap(({ integration }) =>\n integration.intake ? [{ id: integration.id, intake: integration.intake }] : [],\n ),\n }).routes()\n : []),\n ...(deps.factoryReady && deps.knowledgeEnabled\n ? new KnowledgeRoutes({\n auth: deps.auth,\n projects: deps.domains.projects,\n knowledge: async () => deps.factoryStorage?.getMastraStorage().getStore('knowledge'),\n }).routes()\n : []),\n ...(deps.factoryReady\n ? new WorkItemRoutes({\n auth: deps.auth,\n audit: deps.audit,\n projects: deps.domains.projects,\n workItems: deps.domains.workItems,\n boardRegistry: deps.boardRegistry,\n comments: deps.domains.comments,\n queueHealth: deps.domains.queueHealth,\n transitionService,\n startCoordinator,\n liveSessions: deps.liveSessions,\n }).routes()\n : []),\n ...(deps.factoryReady\n ? buildAutomationRunRoutes({\n auth: deps.auth,\n audit: deps.audit,\n projects: deps.domains.projects,\n workItems: deps.domains.workItems,\n configVersion: deps.configVersion,\n })\n : []),\n ];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"surface.js","names":[],"sources":["../../src/routes/surface.ts"],"sourcesContent":["import type { AuthStorage } from '@mastra/code-sdk/auth/storage';\nimport type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentController } from '@mastra/core/agent-controller';\nimport type { ApiRoute, IUserProvider } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { FactoryStorage } from '@mastra/core/storage';\n\nimport { boardForWorkItem } from '../boards/index.js';\nimport type { BoardRegistry } from '../boards/index.js';\nimport type { FactoryIntegration, IntegrationContext } from '../integrations/base.js';\nimport { getGithubFeatureDiagnostics } from '../integrations/github/config.js';\nimport type { GithubIntegration } from '../integrations/github/integration.js';\nimport { MaterializeError } from '../integrations/github/sandbox.js';\nimport { FactoryDispatchError } from '../rules/dispatch-errors.js';\nimport type { FactoryBindingPreparationInput } from '../rules/dispatcher.js';\nimport { FactoryStartCoordinator } from '../rules/start-coordinator.js';\nimport { FactoryTransitionService } from '../rules/transition-service.js';\nimport type { MastraFactorySandboxConfig } from '../sandbox/session-sandbox.js';\nimport {\n createSourceControlSessionLookup,\n ensureFactorySourceSession,\n FactorySourceSessionResolutionError,\n resolveFactoryDefaultModelId,\n resolveFactoryProjectForSession,\n resolveFactorySourceControl,\n} from '../session/factory-session.js';\nimport type { EnsuredFactorySourceSession } from '../session/factory-session.js';\nimport type { LiveSessions } from '../session/live-sessions.js';\nimport type { StateSigner } from '../state-signing.js';\nimport type { AuditEmitter, AuditRecorder } from '../storage/domains/audit/domain.js';\nimport type { ChannelIdentityStorage } from '../storage/domains/channel-identity/base.js';\nimport type { WorkItemCommentsStorage } from '../storage/domains/comments/base.js';\nimport type { CommentsDomain } from '../storage/domains/comments/domain.js';\nimport type { ModelCredentialsStorage } from '../storage/domains/credentials/base.js';\nimport type { CustomProvidersStorage } from '../storage/domains/custom-providers/base.js';\nimport type { FilesystemStorage } from '../storage/domains/filesystem/base.js';\nimport type { IntakeStorage } from '../storage/domains/intake/base.js';\nimport type { IntegrationStorage } from '../storage/domains/integrations/base.js';\nimport type { MemorySettingsStorage } from '../storage/domains/memory-settings/base.js';\nimport type { ModelPacksStorage } from '../storage/domains/model-packs/base.js';\nimport type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';\nimport type { QueueHealthStorage } from '../storage/domains/queue-health/base.js';\nimport {\n SourceControlConnectionNotFoundError,\n type SourceControlStorage,\n type SourceControlStorageHandle,\n} from '../storage/domains/source-control/base.js';\nimport {\n isAgentActor,\n type FactoryDispatchFailureCode,\n type WorkItemsStorage,\n} from '../storage/domains/work-items/base.js';\nimport { workItemBranch, workItemBranchSource, workItemThreadTitle } from '../work-item-branch.js';\nimport { buildAutomationRunRoutes } from './automation-runs.js';\nimport { ConfigRoutes } from './config.js';\nimport { invalidateCustomProvidersSnapshots } from './custom-provider-source.js';\nimport { buildFsRoutes } from './fs.js';\nimport { IntakeRoutes } from './intake.js';\nimport { KnowledgeRoutes } from './knowledge.js';\nimport { OAuthRoutes } from './oauth.js';\nimport type { RouteAuth } from './route.js';\nimport { SkillRoutes } from './skills.js';\nimport { buildSourceControlSessionRoutes } from './source-control-sessions.js';\nimport { buildSourceControlSettingsRoutes } from './source-control-settings.js';\nimport { invalidateTenantCredentialSnapshots } from './tenant-credentials.js';\nimport { WorkItemRoutes } from './work-items.js';\n\nconst MATERIALIZE_FAILURE_CODE = {\n 'git-missing': 'repository_git_missing',\n 'egress-blocked': 'repository_egress_blocked',\n 'clone-failed': 'repository_clone_failed',\n 'pull-failed': 'repository_pull_failed',\n 'push-failed': 'repository_push_failed',\n 'commit-failed': 'repository_commit_failed',\n 'gh-missing': 'repository_cli_missing',\n 'pr-failed': 'repository_pr_failed',\n} satisfies Record<MaterializeError['code'], FactoryDispatchFailureCode>;\nexport interface IntegrationRegistration {\n integration: FactoryIntegration;\n ready: boolean;\n ensureReady: () => Promise<void>;\n}\n\nexport interface FactoryApiRoutesDeps {\n controllerId: string;\n controller: AgentController<MastraCodeState>;\n /** Registry of the sessions this process holds, owned by the host so it can watch them too. */\n liveSessions: LiveSessions;\n /** Request-auth seam threaded from the host (no service locator). */\n auth: RouteAuth;\n /** Optional user directory for resolving persisted owners to display profiles. */\n users?: Pick<IUserProvider, 'getUser' | 'getUsers'>;\n authStorage: AuthStorage;\n audit: AuditEmitter & AuditRecorder;\n fsRoot?: string;\n publicOrigin: string;\n stateSigner?: StateSigner;\n /** Sandbox surface (enablement, provider label, create callback). */\n sandbox?: MastraFactorySandboxConfig;\n /** Root factory storage backend (distributed locks, app-db diagnostics). */\n factoryStorage?: FactoryStorage;\n integrationStorage: IntegrationStorage;\n sourceControlStorage: SourceControlStorage;\n /** App-table domain handles, registered and owned by `MastraFactory.prepare()`. */\n domains: {\n intake: IntakeStorage;\n modelCredentials: ModelCredentialsStorage;\n memorySettings: MemorySettingsStorage;\n customProviders: CustomProvidersStorage;\n filesystem: FilesystemStorage;\n modelPacks: ModelPacksStorage;\n projects: FactoryProjectsStorage;\n queueHealth: QueueHealthStorage;\n workItems: WorkItemsStorage;\n channelIdentity: ChannelIdentityStorage;\n comments: WorkItemCommentsStorage;\n };\n integrations?: IntegrationRegistration[];\n intakeReady: boolean;\n factoryReady: boolean;\n knowledgeEnabled: boolean;\n /** Resolved Factory rule set, threaded from the host (no service locator). */\n configVersion: string;\n /** Boards installed for this Factory instance. */\n boardRegistry: BoardRegistry;\n /** Work-item feed service, handed to integrations that ingest platform messages. */\n feed: CommentsDomain;\n factoryTransitionService?: FactoryTransitionService;\n sessionRetirement?: import('../sandbox/session-retirement.js').SessionRetirementCoordinator;\n onFactoryRuntime?: (runtime: {\n transitionService: FactoryTransitionService;\n prepareBinding?: (input: FactoryBindingPreparationInput) => Promise<void>;\n }) => void;\n}\n\nfunction guardIntegrationRoutes({\n integration,\n ready,\n ensureReady,\n routes,\n}: IntegrationRegistration & { routes: ApiRoute[] }): ApiRoute[] {\n if (ready) return routes;\n return routes.map(route => {\n if ('handler' in route) {\n const handler = route.handler;\n return {\n ...route,\n handler: async (context: Parameters<typeof handler>[0]) => {\n try {\n await ensureReady();\n } catch {\n return context.json(\n { error: 'integration_unavailable', message: `${integration.id} integration is unavailable.` },\n 503,\n );\n }\n return handler(context, async () => {});\n },\n };\n }\n\n const createHandler = route.createHandler;\n return {\n ...route,\n createHandler: async (args: Parameters<typeof createHandler>[0]) => {\n const handler = await createHandler(args);\n return async (context: Parameters<typeof handler>[0]) => {\n try {\n await ensureReady();\n } catch {\n return context.json(\n { error: 'integration_unavailable', message: `${integration.id} integration is unavailable.` },\n 503,\n );\n }\n return handler(context);\n };\n },\n };\n });\n}\n\n/**\n * Resolve the source-control session the work item already holds for this role,\n * when it still resolves to the item's org and factory project. Returns\n * `undefined` when there is no ref or the ref no longer resolves, so the caller\n * falls back to minting one.\n */\nasync function reuseBoundSession(\n sourceControl: SourceControlStorageHandle,\n input: FactoryBindingPreparationInput,\n): Promise<EnsuredFactorySourceSession | undefined> {\n const ref = input.item.sessions[input.role];\n if (!ref) return undefined;\n // At least as strict as the coordinator's resolveSourceSession: a ref it\n // would reject must fall through to minting, not hard-fail the run.\n const resolved = await resolveFactoryProjectForSession({ sourceControl, sessionId: ref.sessionId });\n if (\n !resolved ||\n resolved.orgId !== input.record.orgId ||\n resolved.factoryProjectId !== input.record.factoryProjectId\n ) {\n return undefined;\n }\n const session = await sourceControl.sessions.getBySessionId(ref.sessionId);\n if (!session) return undefined;\n return {\n sessionId: session.sessionId,\n userId: session.userId,\n projectRepositoryId: session.projectRepositoryId,\n branch: session.branch,\n baseBranch: session.baseBranch,\n };\n}\n\n/**\n * Start a factory run for a rule binding: ensure the source-control session the\n * coordinator requires, then hand it to `prepare` along with the factory's\n * default model. Exported for tests — this is the autonomous entry point with no\n * browser and no interactive user, so nothing else would catch a regression in\n * what it forwards.\n */\nexport async function prepareFactoryRuleBinding(\n sourceControlProvider: SourceControlStorageHandle | Pick<GithubIntegration, 'sourceControlStorage'>,\n coordinator: Pick<FactoryStartCoordinator, 'prepare'>,\n projects: FactoryProjectsStorage,\n boards: BoardRegistry,\n input: FactoryBindingPreparationInput,\n): Promise<void> {\n try {\n const sourceControl =\n 'sourceControlStorage' in sourceControlProvider\n ? sourceControlProvider.sourceControlStorage\n : sourceControlProvider;\n const source = workItemBranchSource(input.item.externalSource);\n const branch = workItemBranch({ id: input.item.id, source, metadata: input.item.metadata });\n // Only leaving a resting phase derives a lane from the role: roles don't own lanes,\n // and the Done close-out running in the triage seat must not drag the card back.\n // Both the current phase and the role's lane come from the installed board; an\n // unknown board or phase yields no destination rather than a guessed one.\n const board = boards.get(boardForWorkItem(input.item));\n const currentStage = input.item.stages.length === 1 ? input.item.stages[0] : undefined;\n const currentKind = currentStage === undefined ? undefined : board?.phaseKind(currentStage);\n const destinationStage =\n currentKind === undefined\n ? undefined\n : currentKind === 'resting'\n ? board?.phaseForRole(input.role)\n : currentStage;\n if (!destinationStage) {\n throw new FactoryDispatchError(\n 'unsupported_provider_item',\n `Factory skill invocation has no destination lane (role \"${input.role}\", stages [${input.item.stages.join(', ')}]).`,\n );\n }\n const repositorySlug =\n typeof input.item.metadata?.repository === 'string' ? input.item.metadata.repository : undefined;\n // Re-preparing a binding (server restart, retired controller session) must\n // land in the role's existing session: minting a replacement would repoint\n // the work item, flip the session's owner to the approver, and orphan the\n // previous sandbox.\n const approver = input.record.approvedBy ?? undefined;\n const preparedSession =\n (await reuseBoundSession(sourceControl, input)) ??\n (await ensureFactorySourceSession({\n sourceControl,\n orgId: input.record.orgId,\n factoryProjectId: input.record.factoryProjectId,\n repositorySlug,\n branch,\n // A person who approved the run is its interactive user: attribute it to\n // them, not the repo connector. An agent's pre-approval names no person.\n attributeToUserId: isAgentActor(approver) ? undefined : approver,\n }));\n\n await coordinator.prepare({\n orgId: input.record.orgId,\n userId: preparedSession.userId,\n factoryProjectId: input.record.factoryProjectId,\n sessionId: preparedSession.sessionId,\n defaultModelId: await resolveFactoryDefaultModelId(projects, input.record.factoryProjectId),\n threadTitle: workItemThreadTitle({ source, title: input.item.title, metadata: input.item.metadata }),\n kickoffKey: input.record.id,\n destinationStage,\n workItem: {\n id: input.item.id,\n role: input.role,\n input: {\n externalSource: input.item.externalSource,\n parentWorkItemId: input.item.parentWorkItemId,\n title: input.item.title,\n stages: ['intake'],\n sessions: input.item.sessions,\n metadata: input.item.metadata,\n },\n },\n });\n } catch (error) {\n if (error instanceof FactoryDispatchError) throw error;\n if (error instanceof FactorySourceSessionResolutionError) {\n const code = error.reason === 'connection' ? 'source_control_missing' : 'source_repository_missing';\n throw new FactoryDispatchError(code, error.message, { cause: error });\n }\n if (error instanceof SourceControlConnectionNotFoundError) {\n throw new FactoryDispatchError('source_control_missing', error.message, { cause: error });\n }\n if (error instanceof MaterializeError) {\n throw new FactoryDispatchError(MATERIALIZE_FAILURE_CODE[error.code], error.message, { cause: error });\n }\n throw error;\n }\n}\n\n/**\n * Build the {@link IntegrationContext} handed to an integration when the\n * factory collects its capabilities (routes, workers). One shape everywhere:\n * `assembleFactoryApiRoutes` uses it per registration, and `MastraFactory` uses it\n * when collecting integration workers at finalize.\n */\nexport function buildIntegrationContext(\n deps: Pick<\n FactoryApiRoutesDeps,\n | 'controller'\n | 'publicOrigin'\n | 'auth'\n | 'sandbox'\n | 'users'\n | 'factoryStorage'\n | 'integrationStorage'\n | 'sourceControlStorage'\n | 'integrations'\n > & {\n stateSigner: StateSigner;\n emitAudit?: AuditEmitter['emit'];\n configVersion: string;\n boardRegistry: BoardRegistry;\n factoryReady: boolean;\n /** Work-item feed service, so a channel integration can ingest platform messages. */\n feed: CommentsDomain;\n domains: Pick<\n FactoryApiRoutesDeps['domains'],\n 'projects' | 'intake' | 'workItems' | 'channelIdentity' | 'memorySettings'\n >;\n /**\n * Stable id of the registered source-control-owning integration (today:\n * `'github'` when registered). Every call site must derive and pass it so\n * `routes()`, `channels()`, and `workers()` all see the same context shape.\n */\n sourceControlOwnerId?: string;\n },\n integrationId: string,\n): IntegrationContext {\n return {\n auth: deps.auth,\n sandbox: deps.sandbox,\n ...(deps.users ? { users: deps.users } : {}),\n factoryStorage: deps.factoryStorage,\n baseUrl: deps.publicOrigin,\n controller: deps.controller,\n stateSigner: deps.stateSigner,\n storage: {\n generic: deps.integrationStorage.forIntegration(integrationId),\n sourceControl: deps.sourceControlStorage.forIntegration(integrationId),\n ...(deps.sourceControlOwnerId\n ? { sourceControlOwner: deps.sourceControlStorage.forIntegration(deps.sourceControlOwnerId) }\n : {}),\n sourceControls: (deps.integrations ?? [])\n .filter(({ integration }) => integration.versionControl)\n .map(({ integration }) => deps.sourceControlStorage.forIntegration(integration.id)),\n projects: deps.domains.projects,\n intake: deps.domains.intake,\n channelIdentity: deps.domains.channelIdentity,\n memorySettings: deps.domains.memorySettings,\n },\n ...(deps.factoryReady ? { workItems: deps.domains.workItems, feed: deps.feed } : {}),\n ...(deps.factoryReady\n ? {\n runtime: { configVersion: deps.configVersion, workItems: deps.domains.workItems, boards: deps.boardRegistry },\n }\n : {}),\n ...(deps.emitAudit ? { hooks: { emitAudit: deps.emitAudit } } : {}),\n };\n}\n\n/**\n * Disabled-status stub for the well-known integration ids. The SPA polls\n * `/web/github/status`, `/web/linear/status`, and `/web/jira/status`\n * unconditionally, so when an integration is absent (or not ready) the status\n * contract must still hold. Unknown custom ids get no stub — the SPA doesn't\n * poll them.\n */\nfunction disabledIntegrationStatusRoutes(deps: FactoryApiRoutesDeps, id: string, configured = false): ApiRoute[] {\n if (id === 'github') {\n return [\n registerApiRoute('/web/github/status', {\n method: 'GET',\n requiresAuth: false,\n handler: c =>\n c.json({\n enabled: false,\n connected: false,\n installations: [],\n reason: 'missing_config',\n diagnostics: getGithubFeatureDiagnostics({\n github: undefined,\n auth: deps.auth,\n appDbConfigured: deps.factoryStorage !== undefined,\n stateSigner: deps.stateSigner,\n sandbox: deps.sandbox,\n }),\n }),\n }),\n ];\n }\n if (id === 'linear') {\n return [\n registerApiRoute('/web/linear/status', {\n method: 'GET',\n requiresAuth: false,\n handler: c =>\n c.json({\n enabled: false,\n connected: false,\n workspace: null,\n reason: 'missing_config',\n diagnostics: {\n linearAppConfigured: configured,\n factoryAuthEnabled: deps.auth.enabled(),\n appDbConfigured: true,\n },\n }),\n }),\n ];\n }\n if (id === 'jira') {\n return [\n registerApiRoute('/web/jira/status', {\n method: 'GET',\n requiresAuth: false,\n handler: c =>\n c.json({\n enabled: false,\n configured,\n site: null,\n reason: 'missing_config',\n diagnostics: {\n jiraConfigured: configured,\n factoryAuthEnabled: deps.auth.enabled(),\n appDbConfigured: deps.factoryStorage !== undefined,\n },\n }),\n }),\n ];\n }\n return [];\n}\n\n/**\n * Stub for `GET /web/channel-accounts` when NO Slack integration is\n * registered. The SPA's Connections section polls the path unconditionally;\n * without a stub the SPA fallback serves HTML, which the UI can only read as\n * \"old server / unknown\". The machine-readable reason lets it say the truth:\n * the integration isn't registered.\n *\n * Mounted only for ABSENT slack — a registered integration owns the path via\n * its connect routes (or, when the state signer is unstable, gets no routes\n * at all and the UI falls back to the generic copy). Static payload, leaks\n * nothing → no auth needed, same posture as the github/linear stubs.\n */\nfunction absentSlackChannelAccountsRoutes(): ApiRoute[] {\n return [\n registerApiRoute('/web/channel-accounts', {\n method: 'GET',\n requiresAuth: false,\n handler: c => c.json({ accounts: [], canConnect: false, reason: 'not_registered' }),\n }),\n ];\n}\n\n/**\n * Assemble the custom `/web/*` API routes as Mastra `server.apiRoutes`:\n * - fs browser routes (project picker), confined to `fsRoot`\n * - config routes (provider/API-key/model-pack/OM management)\n * - every registered integration's `routes()` surface (full set when ready,\n * disabled-status stub otherwise), plus stubs for absent known ids\n */\nexport function assembleFactoryApiRoutes(deps: FactoryApiRoutesDeps): ApiRoute[] {\n const emitAudit: AuditEmitter['emit'] = args => deps.audit.emit(args);\n const registrations = deps.integrations ?? [];\n const githubRegistration = registrations.find(({ integration }) => integration.id === 'github');\n const githubStorage = githubRegistration ? deps.sourceControlStorage.forIntegration('github') : undefined;\n const githubIntegration = githubRegistration?.integration as GithubIntegration | undefined;\n const sourceControlRegistrations = registrations.filter(({ integration }) => integration.versionControl);\n const sourceControlIntegrationIds = [\n ...new Set(['github', ...sourceControlRegistrations.map(({ integration }) => integration.id)]),\n ];\n const sourceControls = sourceControlIntegrationIds.map(id => deps.sourceControlStorage.forIntegration(id));\n const sourceControlSessions = createSourceControlSessionLookup(sourceControls);\n\n const integrationRoutes = registrations.flatMap(registration => {\n const { integration } = registration;\n if (!deps.stateSigner) return disabledIntegrationStatusRoutes(deps, integration.id, true);\n const context = buildIntegrationContext(\n {\n ...deps,\n stateSigner: deps.stateSigner,\n emitAudit,\n ...(githubRegistration ? { sourceControlOwnerId: 'github' } : {}),\n },\n integration.id,\n );\n return guardIntegrationRoutes({ ...registration, routes: integration.routes(context) });\n });\n // Session persistence belongs to the linked source-control provider, not to\n // GitHub. Replace legacy GitHub-owned handlers with one resolver spanning\n // the legacy GitHub partition and every registered source-control partition.\n const sharedSessionRouteKeys = new Set([\n 'GET /web/github/projects/:id/sessions',\n 'POST /web/github/projects/:id/sessions',\n 'GET /web/user-sessions/:sessionId',\n 'DELETE /web/user-sessions/:sessionId',\n 'POST /web/user-sessions/:sessionId/title',\n ]);\n const providerRoutes = integrationRoutes.filter(\n route => !sharedSessionRouteKeys.has(route.method + ' ' + route.path),\n );\n const sourceControlSessionRoutes =\n sourceControls.length === 0\n ? []\n : buildSourceControlSessionRoutes({\n auth: deps.auth,\n sourceControls,\n ...(deps.users ? { users: deps.users } : {}),\n controller: deps.controller,\n memorySettings: deps.domains.memorySettings,\n sessionRetirement: deps.sessionRetirement,\n ...(deps.factoryReady ? { workItems: deps.domains.workItems } : {}),\n });\n // Absent known integrations still get their disabled-status stub.\n const absentStubs = ['github', 'linear', 'jira']\n .filter(id => !registrations.some(({ integration }) => integration.id === id))\n .flatMap(id => disabledIntegrationStatusRoutes(deps, id));\n // Absent slack gets the channel-accounts not-registered stub (registered\n // slack owns the path via its own connect routes).\n const slackAbsentStubs = registrations.some(({ integration }) => integration.id === 'slack')\n ? []\n : absentSlackChannelAccountsRoutes();\n\n const transitionService = deps.factoryReady\n ? (deps.factoryTransitionService ??\n new FactoryTransitionService({\n configVersion: deps.configVersion,\n boards: deps.boardRegistry,\n storage: deps.domains.workItems,\n audit: deps.audit,\n }))\n : undefined;\n const startCoordinator = transitionService\n ? new FactoryStartCoordinator(\n deps.controller,\n deps.domains.workItems,\n transitionService,\n request =>\n resolveFactorySourceControl({\n sourceControls,\n orgId: request.orgId,\n factoryProjectId: request.factoryProjectId,\n sessionId: request.sessionId,\n }),\n deps.domains.memorySettings,\n )\n : undefined;\n if (transitionService && startCoordinator) {\n deps.onFactoryRuntime?.({\n transitionService,\n ...(sourceControlRegistrations.length > 0\n ? {\n prepareBinding: async (input: FactoryBindingPreparationInput) => {\n const sourceControl = await resolveFactorySourceControl({\n sourceControls,\n orgId: input.record.orgId,\n factoryProjectId: input.record.factoryProjectId,\n });\n if (!sourceControl) {\n throw new FactoryDispatchError(\n 'source_control_missing',\n 'Factory project has no linked source-control repository.',\n );\n }\n return prepareFactoryRuleBinding(\n sourceControl,\n startCoordinator,\n deps.domains.projects,\n deps.boardRegistry,\n input,\n );\n },\n }\n : {}),\n });\n }\n\n return [\n ...buildFsRoutes({\n root: deps.fsRoot,\n sessionFs: {\n auth: deps.auth,\n sessions: sourceControlSessions,\n filesystem: deps.domains.filesystem,\n },\n }),\n ...new ConfigRoutes({\n auth: deps.auth,\n controller: deps.controller,\n authStorage: deps.authStorage,\n modelCredentials: deps.domains.modelCredentials,\n modelPacks: deps.domains.modelPacks,\n sourceControlSessions,\n memorySettings: deps.domains.memorySettings,\n factoryProjects: deps.domains.projects,\n customProviders: deps.domains.customProviders,\n features: { knowledge: deps.knowledgeEnabled },\n onCredentialsChanged: invalidateTenantCredentialSnapshots,\n onCustomProvidersChanged: invalidateCustomProvidersSnapshots,\n }).routes(),\n ...new OAuthRoutes({\n auth: deps.auth,\n authStorage: deps.authStorage,\n modelCredentials: deps.domains.modelCredentials,\n memorySettings: deps.domains.memorySettings,\n onCredentialsChanged: invalidateTenantCredentialSnapshots,\n }).routes(),\n ...new SkillRoutes({\n auth: deps.auth,\n controllerId: deps.controllerId,\n controller: deps.controller,\n sourceControlStorage: githubStorage,\n ensureSourceControlReady: githubRegistration?.ensureReady,\n }).routes(),\n ...sourceControlSessionRoutes,\n ...(sourceControls.length === 0 ? [] : buildSourceControlSettingsRoutes({ auth: deps.auth, sourceControls })),\n ...providerRoutes,\n ...absentStubs,\n ...slackAbsentStubs,\n ...(deps.intakeReady\n ? new IntakeRoutes({\n auth: deps.auth,\n audit: deps.audit,\n intake: deps.domains.intake,\n projects: deps.domains.projects,\n boardRegistry: deps.boardRegistry,\n // Relocation reads and writes work items, which init fail-soft separately from intake.\n ...(deps.factoryReady ? { workItems: deps.domains.workItems } : {}),\n integrations: (deps.integrations ?? []).flatMap(({ integration }) =>\n integration.intake ? [{ id: integration.id, intake: integration.intake }] : [],\n ),\n }).routes()\n : []),\n ...(deps.factoryReady && deps.knowledgeEnabled\n ? new KnowledgeRoutes({\n auth: deps.auth,\n projects: deps.domains.projects,\n knowledge: async () => deps.factoryStorage?.getMastraStorage().getStore('knowledge'),\n }).routes()\n : []),\n ...(deps.factoryReady\n ? new WorkItemRoutes({\n auth: deps.auth,\n audit: deps.audit,\n projects: deps.domains.projects,\n workItems: deps.domains.workItems,\n boardRegistry: deps.boardRegistry,\n comments: deps.domains.comments,\n queueHealth: deps.domains.queueHealth,\n transitionService,\n startCoordinator,\n liveSessions: deps.liveSessions,\n }).routes()\n : []),\n ...(deps.factoryReady\n ? buildAutomationRunRoutes({\n auth: deps.auth,\n audit: deps.audit,\n projects: deps.domains.projects,\n workItems: deps.domains.workItems,\n configVersion: deps.configVersion,\n })\n : []),\n ];\n}\n"],"mappings":"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"}
@@ -17,6 +17,7 @@
17
17
  */
18
18
  import type { CredentialTenant as SdkCredentialTenant } from '@mastra/code-sdk/agents/credential-resolver';
19
19
  import type { AuthCredential, CredentialStore } from '@mastra/code-sdk/auth/types';
20
+ import type { RequestContext } from '@mastra/core/request-context';
20
21
  import type { MiddlewareHandler } from 'hono';
21
22
  import type { ModelCredentialsStorage } from '../storage/domains/credentials/base.js';
22
23
  import type { RouteAuth } from './route.js';
@@ -45,6 +46,13 @@ export declare class TenantCredentialStore implements CredentialStore {
45
46
  * the `loadStoredApiKeysIntoEnv` env side-channel.
46
47
  */
47
48
  export declare function registerTenantCredentialResolver(credentials: ModelCredentialsStorage): void;
49
+ /**
50
+ * Prime the tenant stores for a request context built outside the web layer,
51
+ * such as a webhook-triggered session run. The auth middleware does this for
52
+ * HTTP requests; a run that starts without one would otherwise resolve its
53
+ * model against an empty snapshot and fail closed. No-op before registration.
54
+ */
55
+ export declare function primeTenantCredentialsForRequestContext(requestContext: RequestContext): Promise<void>;
48
56
  /** Test hook: clear registration and cached tenant snapshots. */
49
57
  export declare function resetTenantCredentialResolverForTests(): void;
50
58
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-credentials.d.ts","sourceRoot":"","sources":["../../src/routes/tenant-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,IAAI,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAG3G,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAEtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5C,qBAAa,qBAAsB,YAAW,eAAe;;IAC3D,QAAQ,CAAC,wBAAwB,SAAS;gBAS9B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,uBAAuB,GAAG,SAAS,EAAE,QAAQ,UAAQ;IAO7G,qEAAqE;IAC/D,WAAW,CAAC,GAAG,SAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BlD,kFAAkF;IAClF,MAAM,IAAI,IAAI;IAMd,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIjD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKrD;;;;;OAKG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAoD/D;AAoBD;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,uBAAuB,GAAG,IAAI,CAE3F;AAED,iEAAiE;AACjE,wBAAgB,qCAAqC,IAAI,IAAI,CAG5D;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASpG;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,MAAM,EACN,WAAW,GACZ,EAAE;IACD,MAAM,EAAE,mBAAmB,CAAC;IAC5B,WAAW,EAAE,uBAAuB,CAAC;CACtC,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhB;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,uBAAuB,CAAC;CACtC,GAAG,iBAAiB,CAgBpB"}
1
+ {"version":3,"file":"tenant-credentials.d.ts","sourceRoot":"","sources":["../../src/routes/tenant-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,IAAI,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAM3G,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAEtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5C,qBAAa,qBAAsB,YAAW,eAAe;;IAC3D,QAAQ,CAAC,wBAAwB,SAAS;gBAS9B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,uBAAuB,GAAG,SAAS,EAAE,QAAQ,UAAQ;IAO7G,qEAAqE;IAC/D,WAAW,CAAC,GAAG,SAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BlD,kFAAkF;IAClF,MAAM,IAAI,IAAI;IAMd,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIjD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKrD;;;;;OAKG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAoD/D;AAqBD;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,uBAAuB,GAAG,IAAI,CAG3F;AAED;;;;;GAKG;AACH,wBAAsB,uCAAuC,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3G;AAED,iEAAiE;AACjE,wBAAgB,qCAAqC,IAAI,IAAI,CAI5D;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASpG;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,MAAM,EACN,WAAW,GACZ,EAAE;IACD,MAAM,EAAE,mBAAmB,CAAC;IAC5B,WAAW,EAAE,uBAAuB,CAAC;CACtC,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhB;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,uBAAuB,CAAC;CACtC,GAAG,iBAAiB,CAgBpB"}
@@ -1,6 +1,6 @@
1
- import { getTenantCredentialsStorage, tenantOrgId } from "./provider-credentials.js";
2
1
  import { isOAuthCredentialExpired } from "../storage/domains/credentials/base.js";
3
- import { setCredentialStoreProvider } from "@mastra/code-sdk/agents/credential-resolver";
2
+ import { getTenantCredentialsStorage, tenantOrgId } from "./provider-credentials.js";
3
+ import { resolveTenantFromRequestContext, setCredentialStoreProvider } from "@mastra/code-sdk/agents/credential-resolver";
4
4
  import { getOAuthProvider } from "@mastra/code-sdk/auth/storage";
5
5
  //#region src/routes/tenant-credentials.ts
6
6
  /** How long a hydrated snapshot is considered fresh. */
@@ -94,6 +94,7 @@ var TenantCredentialStore = class {
94
94
  }
95
95
  };
96
96
  const tenantStores = /* @__PURE__ */ new Map();
97
+ let registeredCredentials;
97
98
  function storeFor(tenant, credentials) {
98
99
  const orgId = tenantOrgId(tenant);
99
100
  const orgFirst = tenant.orgFirst === true;
@@ -116,11 +117,27 @@ function storeFor(tenant, credentials) {
116
117
  * the `loadStoredApiKeysIntoEnv` env side-channel.
117
118
  */
118
119
  function registerTenantCredentialResolver(credentials) {
120
+ registeredCredentials = credentials;
119
121
  setCredentialStoreProvider((tenant) => storeFor(tenant, credentials));
120
122
  }
123
+ /**
124
+ * Prime the tenant stores for a request context built outside the web layer,
125
+ * such as a webhook-triggered session run. The auth middleware does this for
126
+ * HTTP requests; a run that starts without one would otherwise resolve its
127
+ * model against an empty snapshot and fail closed. No-op before registration.
128
+ */
129
+ async function primeTenantCredentialsForRequestContext(requestContext) {
130
+ const tenant = resolveTenantFromRequestContext(requestContext);
131
+ if (!tenant || !registeredCredentials) return;
132
+ await primeTenantCredentials({
133
+ tenant,
134
+ credentials: registeredCredentials
135
+ });
136
+ }
121
137
  /** Test hook: clear registration and cached tenant snapshots. */
122
138
  function resetTenantCredentialResolverForTests() {
123
139
  setCredentialStoreProvider(void 0);
140
+ registeredCredentials = void 0;
124
141
  tenantStores.clear();
125
142
  }
126
143
  /**
@@ -171,6 +188,6 @@ function createTenantCredentialPrimer({ auth, credentials }) {
171
188
  };
172
189
  }
173
190
  //#endregion
174
- export { TenantCredentialStore, createTenantCredentialPrimer, invalidateTenantCredentialSnapshots, primeTenantCredentials, registerTenantCredentialResolver, resetTenantCredentialResolverForTests };
191
+ export { TenantCredentialStore, createTenantCredentialPrimer, invalidateTenantCredentialSnapshots, primeTenantCredentials, primeTenantCredentialsForRequestContext, registerTenantCredentialResolver, resetTenantCredentialResolverForTests };
175
192
 
176
193
  //# sourceMappingURL=tenant-credentials.js.map