@mastra/factory 0.13.0-alpha.9 → 0.13.0

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 (232) hide show
  1. package/README.md +232 -10
  2. package/dist/auth.d.ts +2 -0
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +29 -4
  5. package/dist/auth.js.map +1 -1
  6. package/dist/boards/define-board.d.ts +36 -2
  7. package/dist/boards/define-board.d.ts.map +1 -1
  8. package/dist/boards/define-board.js +58 -1
  9. package/dist/boards/define-board.js.map +1 -1
  10. package/dist/boards/index.d.ts +4 -2
  11. package/dist/boards/index.d.ts.map +1 -1
  12. package/dist/boards/index.js +2 -1
  13. package/dist/boards/index.js.map +1 -1
  14. package/dist/boards/relocate.d.ts +17 -0
  15. package/dist/boards/relocate.d.ts.map +1 -0
  16. package/dist/boards/relocate.js +53 -0
  17. package/dist/boards/relocate.js.map +1 -0
  18. package/dist/boards/review.d.ts +1 -1
  19. package/dist/boards/review.d.ts.map +1 -1
  20. package/dist/boards/review.js +17 -4
  21. package/dist/boards/review.js.map +1 -1
  22. package/dist/boards/semantics.d.ts +28 -0
  23. package/dist/boards/semantics.d.ts.map +1 -0
  24. package/dist/boards/semantics.js +41 -0
  25. package/dist/boards/semantics.js.map +1 -0
  26. package/dist/boards/work-tool-rules.d.ts +8 -0
  27. package/dist/boards/work-tool-rules.d.ts.map +1 -0
  28. package/dist/boards/work-tool-rules.js +20 -0
  29. package/dist/boards/work-tool-rules.js.map +1 -0
  30. package/dist/boards/work.d.ts +1 -1
  31. package/dist/boards/work.d.ts.map +1 -1
  32. package/dist/boards/work.js +13 -0
  33. package/dist/boards/work.js.map +1 -1
  34. package/dist/capabilities/intake.d.ts +2 -0
  35. package/dist/capabilities/intake.d.ts.map +1 -1
  36. package/dist/factory.d.ts +5 -6
  37. package/dist/factory.d.ts.map +1 -1
  38. package/dist/factory.js +41 -12
  39. package/dist/factory.js.map +1 -1
  40. package/dist/integrations/base.d.ts +7 -4
  41. package/dist/integrations/base.d.ts.map +1 -1
  42. package/dist/integrations/github/default-rules.d.ts +2 -2
  43. package/dist/integrations/github/default-rules.d.ts.map +1 -1
  44. package/dist/integrations/github/default-rules.js +2 -2
  45. package/dist/integrations/github/default-rules.js.map +1 -1
  46. package/dist/integrations/github/issue-reconciler.d.ts.map +1 -1
  47. package/dist/integrations/github/issue-reconciler.js +4 -3
  48. package/dist/integrations/github/issue-reconciler.js.map +1 -1
  49. package/dist/integrations/github/rules.d.ts +6 -2
  50. package/dist/integrations/github/rules.d.ts.map +1 -1
  51. package/dist/integrations/github/rules.js +96 -15
  52. package/dist/integrations/github/rules.js.map +1 -1
  53. package/dist/integrations/github/sandbox.d.ts +6 -3
  54. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  55. package/dist/integrations/github/sandbox.js +21 -2
  56. package/dist/integrations/github/sandbox.js.map +1 -1
  57. package/dist/integrations/issue-reconciler.d.ts +2 -0
  58. package/dist/integrations/issue-reconciler.d.ts.map +1 -1
  59. package/dist/integrations/issue-reconciler.js +1 -3
  60. package/dist/integrations/issue-reconciler.js.map +1 -1
  61. package/dist/integrations/linear/agent-tools.d.ts.map +1 -1
  62. package/dist/integrations/linear/agent-tools.js.map +1 -1
  63. package/dist/integrations/linear/default-rules.d.ts +2 -2
  64. package/dist/integrations/linear/default-rules.d.ts.map +1 -1
  65. package/dist/integrations/linear/default-rules.js +2 -2
  66. package/dist/integrations/linear/default-rules.js.map +1 -1
  67. package/dist/integrations/linear/integration.js +1 -0
  68. package/dist/integrations/linear/integration.js.map +1 -1
  69. package/dist/integrations/linear/issue-reconciler.d.ts.map +1 -1
  70. package/dist/integrations/linear/issue-reconciler.js +9 -4
  71. package/dist/integrations/linear/issue-reconciler.js.map +1 -1
  72. package/dist/integrations/linear/reconciliation-config.d.ts.map +1 -1
  73. package/dist/integrations/linear/reconciliation-config.js.map +1 -1
  74. package/dist/integrations/linear/routes.d.ts.map +1 -1
  75. package/dist/integrations/linear/routes.js +19 -26
  76. package/dist/integrations/linear/routes.js.map +1 -1
  77. package/dist/integrations/linear/rules.d.ts +7 -2
  78. package/dist/integrations/linear/rules.d.ts.map +1 -1
  79. package/dist/integrations/linear/rules.js +20 -8
  80. package/dist/integrations/linear/rules.js.map +1 -1
  81. package/dist/integrations/platform/api-client.d.ts.map +1 -1
  82. package/dist/integrations/platform/api-client.js +25 -4
  83. package/dist/integrations/platform/api-client.js.map +1 -1
  84. package/dist/integrations/platform/github/integration.d.ts +1 -0
  85. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  86. package/dist/integrations/platform/github/integration.js +5 -0
  87. package/dist/integrations/platform/github/integration.js.map +1 -1
  88. package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
  89. package/dist/integrations/platform/linear/integration.js +5 -2
  90. package/dist/integrations/platform/linear/integration.js.map +1 -1
  91. package/dist/integrations/slack/emoji-shortcodes.generated.d.ts +8 -0
  92. package/dist/integrations/slack/emoji-shortcodes.generated.d.ts.map +1 -0
  93. package/dist/integrations/slack/emoji-shortcodes.generated.js +1985 -0
  94. package/dist/integrations/slack/emoji-shortcodes.generated.js.map +1 -0
  95. package/dist/integrations/slack/emoji.d.ts +3 -0
  96. package/dist/integrations/slack/emoji.d.ts.map +1 -0
  97. package/dist/integrations/slack/emoji.js +12 -0
  98. package/dist/integrations/slack/emoji.js.map +1 -0
  99. package/dist/integrations/slack/integration.js +1 -1
  100. package/dist/integrations/slack/integration.js.map +1 -1
  101. package/dist/integrations/slack/slack.d.ts.map +1 -1
  102. package/dist/integrations/slack/slack.js +16 -2
  103. package/dist/integrations/slack/slack.js.map +1 -1
  104. package/dist/routes/attention-activity.d.ts +2 -3
  105. package/dist/routes/attention-activity.d.ts.map +1 -1
  106. package/dist/routes/attention-activity.js +12 -3
  107. package/dist/routes/attention-activity.js.map +1 -1
  108. package/dist/routes/attention-parked.d.ts +22 -0
  109. package/dist/routes/attention-parked.d.ts.map +1 -0
  110. package/dist/routes/attention-parked.js +136 -0
  111. package/dist/routes/attention-parked.js.map +1 -0
  112. package/dist/routes/attention-providers.js +8 -8
  113. package/dist/routes/attention-providers.js.map +1 -1
  114. package/dist/routes/attention.d.ts +2 -0
  115. package/dist/routes/attention.d.ts.map +1 -1
  116. package/dist/routes/attention.js +47 -118
  117. package/dist/routes/attention.js.map +1 -1
  118. package/dist/routes/contracts.d.ts +627 -0
  119. package/dist/routes/contracts.d.ts.map +1 -0
  120. package/dist/routes/contracts.js +468 -0
  121. package/dist/routes/contracts.js.map +1 -0
  122. package/dist/routes/intake.d.ts +18 -0
  123. package/dist/routes/intake.d.ts.map +1 -1
  124. package/dist/routes/intake.js +265 -15
  125. package/dist/routes/intake.js.map +1 -1
  126. package/dist/routes/projects.d.ts.map +1 -1
  127. package/dist/routes/projects.js +26 -76
  128. package/dist/routes/projects.js.map +1 -1
  129. package/dist/routes/supervisor.d.ts +2 -0
  130. package/dist/routes/supervisor.d.ts.map +1 -1
  131. package/dist/routes/supervisor.js +7 -6
  132. package/dist/routes/supervisor.js.map +1 -1
  133. package/dist/routes/surface.d.ts +7 -4
  134. package/dist/routes/surface.d.ts.map +1 -1
  135. package/dist/routes/surface.js +17 -11
  136. package/dist/routes/surface.js.map +1 -1
  137. package/dist/routes/telemetry.d.ts +13 -0
  138. package/dist/routes/telemetry.d.ts.map +1 -0
  139. package/dist/routes/telemetry.js +60 -0
  140. package/dist/routes/telemetry.js.map +1 -0
  141. package/dist/routes/work-items.d.ts +3 -3
  142. package/dist/routes/work-items.d.ts.map +1 -1
  143. package/dist/routes/work-items.js +134 -250
  144. package/dist/routes/work-items.js.map +1 -1
  145. package/dist/rules/dispatch-errors.d.ts +2 -2
  146. package/dist/rules/dispatch-errors.d.ts.map +1 -1
  147. package/dist/rules/dispatch-errors.js +10 -6
  148. package/dist/rules/dispatch-errors.js.map +1 -1
  149. package/dist/rules/dispatcher.d.ts +9 -2
  150. package/dist/rules/dispatcher.d.ts.map +1 -1
  151. package/dist/rules/dispatcher.js +76 -23
  152. package/dist/rules/dispatcher.js.map +1 -1
  153. package/dist/rules/index.d.ts +4 -5
  154. package/dist/rules/index.d.ts.map +1 -1
  155. package/dist/rules/index.js +3 -4
  156. package/dist/rules/processor.d.ts +3 -3
  157. package/dist/rules/processor.d.ts.map +1 -1
  158. package/dist/rules/processor.js +24 -31
  159. package/dist/rules/processor.js.map +1 -1
  160. package/dist/rules/resolve.d.ts +1 -3
  161. package/dist/rules/resolve.d.ts.map +1 -1
  162. package/dist/rules/resolve.js +1 -4
  163. package/dist/rules/resolve.js.map +1 -1
  164. package/dist/rules/start-coordinator.d.ts.map +1 -1
  165. package/dist/rules/start-coordinator.js +3 -1
  166. package/dist/rules/start-coordinator.js.map +1 -1
  167. package/dist/rules/tools.d.ts.map +1 -1
  168. package/dist/rules/tools.js +20 -10
  169. package/dist/rules/tools.js.map +1 -1
  170. package/dist/rules/transition-service.d.ts +7 -7
  171. package/dist/rules/transition-service.d.ts.map +1 -1
  172. package/dist/rules/transition-service.js +21 -25
  173. package/dist/rules/transition-service.js.map +1 -1
  174. package/dist/rules/types.d.ts +16 -11
  175. package/dist/rules/types.d.ts.map +1 -1
  176. package/dist/rules/types.js.map +1 -1
  177. package/dist/rules/validation.d.ts +12 -2
  178. package/dist/rules/validation.d.ts.map +1 -1
  179. package/dist/rules/validation.js +29 -20
  180. package/dist/rules/validation.js.map +1 -1
  181. package/dist/session/live-sessions.d.ts +33 -3
  182. package/dist/session/live-sessions.d.ts.map +1 -1
  183. package/dist/session/live-sessions.js +67 -5
  184. package/dist/session/live-sessions.js.map +1 -1
  185. package/dist/storage/domains/intake/base.d.ts +54 -1
  186. package/dist/storage/domains/intake/base.d.ts.map +1 -1
  187. package/dist/storage/domains/intake/base.js +136 -4
  188. package/dist/storage/domains/intake/base.js.map +1 -1
  189. package/dist/storage/domains/work-items/base.d.ts +22 -7
  190. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  191. package/dist/storage/domains/work-items/base.js +41 -26
  192. package/dist/storage/domains/work-items/base.js.map +1 -1
  193. package/dist/supervisor/health-worker.d.ts +2 -0
  194. package/dist/supervisor/health-worker.d.ts.map +1 -1
  195. package/dist/supervisor/health-worker.js +3 -1
  196. package/dist/supervisor/health-worker.js.map +1 -1
  197. package/dist/supervisor/health.d.ts +12 -14
  198. package/dist/supervisor/health.d.ts.map +1 -1
  199. package/dist/supervisor/health.js +24 -52
  200. package/dist/supervisor/health.js.map +1 -1
  201. package/dist/supervisor/instructions.d.ts +1 -1
  202. package/dist/supervisor/instructions.d.ts.map +1 -1
  203. package/dist/supervisor/instructions.js +10 -8
  204. package/dist/supervisor/instructions.js.map +1 -1
  205. package/dist/supervisor/read-tools.d.ts +2 -0
  206. package/dist/supervisor/read-tools.d.ts.map +1 -1
  207. package/dist/supervisor/read-tools.js +2 -2
  208. package/dist/supervisor/read-tools.js.map +1 -1
  209. package/dist/supervisor/write-tools.d.ts.map +1 -1
  210. package/dist/supervisor/write-tools.js +6 -4
  211. package/dist/supervisor/write-tools.js.map +1 -1
  212. package/dist/telemetry-types.d.ts +7 -0
  213. package/dist/telemetry-types.d.ts.map +1 -0
  214. package/dist/telemetry-types.js +24 -0
  215. package/dist/telemetry-types.js.map +1 -0
  216. package/dist/telemetry.d.ts +9 -0
  217. package/dist/telemetry.d.ts.map +1 -0
  218. package/dist/telemetry.js +47 -0
  219. package/dist/telemetry.js.map +1 -0
  220. package/dist/work-item-branch.d.ts +2 -0
  221. package/dist/work-item-branch.d.ts.map +1 -1
  222. package/dist/work-item-branch.js +6 -1
  223. package/dist/work-item-branch.js.map +1 -1
  224. package/dist/workspace.d.ts.map +1 -1
  225. package/dist/workspace.js +3 -1
  226. package/dist/workspace.js.map +1 -1
  227. package/factory-skills/configure-factory-rules/SKILL.md +30 -10
  228. package/package.json +12 -10
  229. package/dist/rules/defaults.d.ts +0 -9
  230. package/dist/rules/defaults.d.ts.map +0 -1
  231. package/dist/rules/defaults.js +0 -50
  232. package/dist/rules/defaults.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/integrations/linear/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiD,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAExG,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AACrF,OAAO,KAAK,EAAe,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC9F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAkB3D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC9C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,KAAK,EAAE,YAAY,CAAC;IACpB,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,KAAK,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAE1D,qBAAa,WAAW;;IACV,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,kBAAkB;IAElD,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAiG9F;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,EAC5C,OAAO,EAAE,kBAAkB,GAC1B,CAAC,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAS/D"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/integrations/linear/rules.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AACrF,OAAO,KAAK,EAAe,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC9F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAkB3D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC9C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED,KAAK,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAE1D,qBAAa,WAAW;;IACV,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,kBAAkB;IAElD,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CA2G9F;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,EAC5C,OAAO,EAAE,kBAAkB,GAC1B,CAAC,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAU/D"}
@@ -1,4 +1,6 @@
1
- import { validateFactoryRuleDecisions } from "../../rules/validation.js";
1
+ import { assertFactoryDecisionTarget, validateFactoryRuleDecisions } from "../../rules/validation.js";
2
+ import { boardForWorkItem } from "../../boards/semantics.js";
3
+ import "../../boards/index.js";
2
4
  //#region src/integrations/linear/rules.ts
3
5
  const RULE_TIMEOUT_MS = 5e3;
4
6
  async function withRuleTimeout(promise) {
@@ -53,6 +55,8 @@ var LinearRules = class {
53
55
  const isClosed = issue.stateType === "completed" || issue.stateType === "canceled";
54
56
  if (isClosed && !relatedItem) return "missing";
55
57
  const event = isClosed ? "issueClosed" : "issueObserved";
58
+ const boundBoardId = issue.sourceId ? input.intakeBoards?.[issue.sourceId] : void 0;
59
+ const boundBoard = boundBoardId ? this.options.boards.get(boundBoardId) : void 0;
56
60
  const context = {
57
61
  tenant: {
58
62
  orgId: input.orgId,
@@ -65,7 +69,7 @@ var LinearRules = class {
65
69
  },
66
70
  cause: `linear.${event}`,
67
71
  causalChain: [],
68
- ruleSetVersion: this.options.rules.version,
72
+ configVersion: this.options.configVersion,
69
73
  ...relatedItem ? {
70
74
  item: {
71
75
  id: relatedItem.id,
@@ -78,9 +82,13 @@ var LinearRules = class {
78
82
  acceptedAt: relatedItem.acceptedAt,
79
83
  metadata: relatedItem.metadata
80
84
  },
81
- board: "work",
85
+ board: boardForWorkItem(relatedItem),
82
86
  itemRevision: relatedItem.revision
83
87
  } : {},
88
+ ...boundBoard ? { intake: {
89
+ board: boundBoard.id,
90
+ initialPhase: boundBoard.initialPhase
91
+ } } : {},
84
92
  event,
85
93
  issue
86
94
  };
@@ -95,7 +103,10 @@ var LinearRules = class {
95
103
  code: decision.code,
96
104
  reason: decision.reason
97
105
  };
98
- else if (decision) decisions = validateFactoryRuleDecisions([decision]).map((entry) => ({ ...entry }));
106
+ else if (decision) decisions = validateFactoryRuleDecisions([decision]).map((entry) => {
107
+ assertFactoryDecisionTarget(entry, this.options.boards, relatedItem ? boardForWorkItem(relatedItem) : void 0);
108
+ return { ...entry };
109
+ });
99
110
  } catch (error) {
100
111
  const timedOut = error instanceof Error && error.message === "FACTORY_RULE_TIMEOUT";
101
112
  outcome = {
@@ -112,7 +123,7 @@ var LinearRules = class {
112
123
  identity: ingressId,
113
124
  triggerType: "linear.issueObserved"
114
125
  },
115
- ruleSetVersion: this.options.rules.version,
126
+ configVersion: this.options.configVersion,
116
127
  expectedRevision: relatedItem?.revision ?? null,
117
128
  actor,
118
129
  outcome,
@@ -123,11 +134,12 @@ var LinearRules = class {
123
134
  }
124
135
  };
125
136
  function attachLinearRules(linear, context) {
126
- if (!context.rules) return void 0;
137
+ if (!context.runtime) return void 0;
127
138
  const rules = new LinearRules({
128
139
  projects: context.storage.projects,
129
- storage: context.rules.workItems,
130
- rules: context.rules.config,
140
+ storage: context.runtime.workItems,
141
+ configVersion: context.runtime.configVersion,
142
+ boards: context.runtime.boards,
131
143
  linearRules: linear.rules
132
144
  });
133
145
  return (input) => rules.ingest(input);
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","names":["#ingestIssue"],"sources":["../../../src/integrations/linear/rules.ts"],"sourcesContent":["import type { FactoryLinearRuleContext, FactoryRuleDecision, FactoryRules } from '../../rules/types.js';\nimport { validateFactoryRuleDecisions } from '../../rules/validation.js';\nimport type { FactoryProjectsStorage } from '../../storage/domains/projects/base.js';\nimport type { WorkItemRow, WorkItemsStorage } from '../../storage/domains/work-items/base.js';\nimport type { IntegrationContext } from '../base.js';\nimport type { LinearEventRules } from './default-rules.js';\n\nconst RULE_TIMEOUT_MS = 5_000;\n\nasync function withRuleTimeout<T>(promise: Promise<T>): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => reject(new Error('FACTORY_RULE_TIMEOUT')), RULE_TIMEOUT_MS);\n }),\n ]);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nexport interface LinearIssueIngress {\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n /** Display name of the Linear user who created the issue, when available. */\n creator: string | null;\n team: string | null;\n labels: string[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LinearRulesOptions {\n projects: Pick<FactoryProjectsStorage, 'get'>;\n storage: WorkItemsStorage;\n rules: FactoryRules;\n linearRules: LinearEventRules;\n}\n\nexport interface LinearRulesIngress {\n orgId: string;\n userId: string;\n factoryProjectId: string;\n issues: LinearIssueIngress[];\n}\n\ntype IngressStatus = 'committed' | 'replayed' | 'missing';\n\nexport class LinearRules {\n constructor(private readonly options: LinearRulesOptions) {}\n\n async ingest(input: LinearRulesIngress): Promise<{ status: IngressStatus; ingested: number }> {\n const project = await this.options.projects.get({ orgId: input.orgId, id: input.factoryProjectId });\n if (!project) return { status: 'missing', ingested: 0 };\n\n const items = await this.options.storage.list({ orgId: input.orgId, factoryProjectId: input.factoryProjectId });\n const itemsBySourceKey = new Map(items.map(item => [item.externalSource?.externalId, item]));\n const statuses: IngressStatus[] = [];\n for (const issue of input.issues) {\n statuses.push(await this.#ingestIssue(input, issue, itemsBySourceKey.get(`linear:${issue.identifier}`)));\n }\n if (statuses.some(status => status === 'committed')) return { status: 'committed', ingested: statuses.length };\n if (statuses.some(status => status === 'replayed')) return { status: 'replayed', ingested: statuses.length };\n return { status: 'missing', ingested: statuses.length };\n }\n\n async #ingestIssue(\n input: LinearRulesIngress,\n issue: LinearIssueIngress,\n relatedItem: WorkItemRow | undefined,\n ): Promise<IngressStatus> {\n const ingressId = `linear:${issue.id}:${issue.updatedAt}`;\n const actor = { type: 'human' as const, id: input.userId };\n\n // Closed issues without existing work items should not create new ones.\n const isClosed = issue.stateType === 'completed' || issue.stateType === 'canceled';\n if (isClosed && !relatedItem) {\n return 'missing';\n }\n\n const event = isClosed ? 'issueClosed' : 'issueObserved';\n const context: FactoryLinearRuleContext = {\n tenant: { orgId: input.orgId, projectId: input.factoryProjectId },\n actor,\n ingress: { type: 'linear', id: ingressId },\n cause: `linear.${event}`,\n causalChain: [],\n ruleSetVersion: this.options.rules.version,\n ...(relatedItem\n ? {\n item: {\n id: relatedItem.id,\n source: 'linear-issue',\n sourceKey: relatedItem.externalSource?.externalId ?? null,\n parentWorkItemId: relatedItem.parentWorkItemId,\n title: relatedItem.title,\n url: relatedItem.externalSource?.url ?? null,\n stages: relatedItem.stages,\n acceptedAt: relatedItem.acceptedAt,\n metadata: relatedItem.metadata,\n },\n board: 'work' as const,\n itemRevision: relatedItem.revision,\n }\n : {}),\n event,\n issue,\n };\n\n const rule = this.options.linearRules[context.event];\n let decision: FactoryRuleDecision | void;\n let decisions: Record<string, unknown>[] = [];\n let outcome: { status: 'accepted' | 'rejected'; code?: string; reason?: string } = { status: 'accepted' };\n try {\n decision = rule ? await withRuleTimeout(Promise.resolve(rule(Object.freeze(context)))) : undefined;\n if (decision?.type === 'reject') {\n outcome = { status: 'rejected', code: decision.code, reason: decision.reason };\n } else if (decision) {\n decisions = validateFactoryRuleDecisions([decision]).map(entry => ({ ...entry }));\n }\n } catch (error) {\n const timedOut = error instanceof Error && error.message === 'FACTORY_RULE_TIMEOUT';\n outcome = {\n status: 'rejected',\n code: timedOut ? 'timeout' : 'rule_error',\n reason: timedOut\n ? 'Factory rule evaluation timed out.'\n : error instanceof Error\n ? error.message.slice(0, 2_000)\n : 'Factory Linear rule failed.',\n };\n }\n\n const committed = await this.options.storage.commitRuleEvaluation({\n orgId: input.orgId,\n factoryProjectId: input.factoryProjectId,\n workItemId: relatedItem?.id ?? null,\n ingress: { identity: ingressId, triggerType: 'linear.issueObserved' },\n ruleSetVersion: this.options.rules.version,\n expectedRevision: relatedItem?.revision ?? null,\n actor,\n outcome,\n decisions,\n causalChain: [],\n now: new Date(),\n });\n return committed.status;\n }\n}\n\nexport function attachLinearRules(\n linear: { readonly rules: LinearEventRules },\n context: IntegrationContext,\n): ((input: LinearRulesIngress) => Promise<unknown>) | undefined {\n if (!context.rules) return undefined;\n const rules = new LinearRules({\n projects: context.storage.projects,\n storage: context.rules.workItems,\n rules: context.rules.config,\n linearRules: linear.rules,\n });\n return input => rules.ingest(input);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rules.js","names":["#ingestIssue"],"sources":["../../../src/integrations/linear/rules.ts"],"sourcesContent":["import { boardForWorkItem } from '../../boards/index.js';\nimport type { BoardRegistry } from '../../boards/index.js';\nimport type { FactoryLinearRuleContext, FactoryRuleDecision } from '../../rules/types.js';\nimport { assertFactoryDecisionTarget, validateFactoryRuleDecisions } from '../../rules/validation.js';\nimport type { FactoryProjectsStorage } from '../../storage/domains/projects/base.js';\nimport type { WorkItemRow, WorkItemsStorage } from '../../storage/domains/work-items/base.js';\nimport type { IntegrationContext } from '../base.js';\nimport type { LinearEventRules } from './default-rules.js';\n\nconst RULE_TIMEOUT_MS = 5_000;\n\nasync function withRuleTimeout<T>(promise: Promise<T>): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => reject(new Error('FACTORY_RULE_TIMEOUT')), RULE_TIMEOUT_MS);\n }),\n ]);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nexport interface LinearIssueIngress {\n id: string;\n identifier: string;\n title: string;\n url: string;\n state: string;\n stateType: string;\n priorityLabel: string;\n assignee: string | null;\n /** Display name of the Linear user who created the issue, when available. */\n creator: string | null;\n team: string | null;\n labels: string[];\n createdAt: string;\n updatedAt: string;\n /** Linear project the issue was read from; resolves the bound board via `intakeBoards`. */\n sourceId?: string | null;\n}\n\nexport interface LinearRulesOptions {\n projects: Pick<FactoryProjectsStorage, 'get'>;\n storage: WorkItemsStorage;\n configVersion: string;\n boards: BoardRegistry;\n linearRules: LinearEventRules;\n}\n\nexport interface LinearRulesIngress {\n orgId: string;\n userId: string;\n factoryProjectId: string;\n issues: LinearIssueIngress[];\n /** Board id per bound Linear source id, from the project's intake bindings. */\n intakeBoards?: Readonly<Record<string, string>>;\n}\n\ntype IngressStatus = 'committed' | 'replayed' | 'missing';\n\nexport class LinearRules {\n constructor(private readonly options: LinearRulesOptions) {}\n\n async ingest(input: LinearRulesIngress): Promise<{ status: IngressStatus; ingested: number }> {\n const project = await this.options.projects.get({ orgId: input.orgId, id: input.factoryProjectId });\n if (!project) return { status: 'missing', ingested: 0 };\n\n const items = await this.options.storage.list({ orgId: input.orgId, factoryProjectId: input.factoryProjectId });\n const itemsBySourceKey = new Map(items.map(item => [item.externalSource?.externalId, item]));\n const statuses: IngressStatus[] = [];\n for (const issue of input.issues) {\n statuses.push(await this.#ingestIssue(input, issue, itemsBySourceKey.get(`linear:${issue.identifier}`)));\n }\n if (statuses.some(status => status === 'committed')) return { status: 'committed', ingested: statuses.length };\n if (statuses.some(status => status === 'replayed')) return { status: 'replayed', ingested: statuses.length };\n return { status: 'missing', ingested: statuses.length };\n }\n\n async #ingestIssue(\n input: LinearRulesIngress,\n issue: LinearIssueIngress,\n relatedItem: WorkItemRow | undefined,\n ): Promise<IngressStatus> {\n const ingressId = `linear:${issue.id}:${issue.updatedAt}`;\n const actor = { type: 'human' as const, id: input.userId };\n\n // Closed issues without existing work items should not create new ones.\n const isClosed = issue.stateType === 'completed' || issue.stateType === 'canceled';\n if (isClosed && !relatedItem) {\n return 'missing';\n }\n\n const event = isClosed ? 'issueClosed' : 'issueObserved';\n const boundBoardId = issue.sourceId ? input.intakeBoards?.[issue.sourceId] : undefined;\n const boundBoard = boundBoardId ? this.options.boards.get(boundBoardId) : undefined;\n const context: FactoryLinearRuleContext = {\n tenant: { orgId: input.orgId, projectId: input.factoryProjectId },\n actor,\n ingress: { type: 'linear', id: ingressId },\n cause: `linear.${event}`,\n causalChain: [],\n configVersion: this.options.configVersion,\n ...(relatedItem\n ? {\n item: {\n id: relatedItem.id,\n source: 'linear-issue',\n sourceKey: relatedItem.externalSource?.externalId ?? null,\n parentWorkItemId: relatedItem.parentWorkItemId,\n title: relatedItem.title,\n url: relatedItem.externalSource?.url ?? null,\n stages: relatedItem.stages,\n acceptedAt: relatedItem.acceptedAt,\n metadata: relatedItem.metadata,\n },\n board: boardForWorkItem(relatedItem),\n itemRevision: relatedItem.revision,\n }\n : {}),\n ...(boundBoard ? { intake: { board: boundBoard.id, initialPhase: boundBoard.initialPhase } } : {}),\n event,\n issue,\n };\n\n const rule = this.options.linearRules[context.event];\n let decision: FactoryRuleDecision | void;\n let decisions: Record<string, unknown>[] = [];\n let outcome: { status: 'accepted' | 'rejected'; code?: string; reason?: string } = { status: 'accepted' };\n try {\n decision = rule ? await withRuleTimeout(Promise.resolve(rule(Object.freeze(context)))) : undefined;\n if (decision?.type === 'reject') {\n outcome = { status: 'rejected', code: decision.code, reason: decision.reason };\n } else if (decision) {\n decisions = validateFactoryRuleDecisions([decision]).map(entry => {\n assertFactoryDecisionTarget(\n entry,\n this.options.boards,\n relatedItem ? boardForWorkItem(relatedItem) : undefined,\n );\n return { ...entry };\n });\n }\n } catch (error) {\n const timedOut = error instanceof Error && error.message === 'FACTORY_RULE_TIMEOUT';\n outcome = {\n status: 'rejected',\n code: timedOut ? 'timeout' : 'rule_error',\n reason: timedOut\n ? 'Factory rule evaluation timed out.'\n : error instanceof Error\n ? error.message.slice(0, 2_000)\n : 'Factory Linear rule failed.',\n };\n }\n\n const committed = await this.options.storage.commitRuleEvaluation({\n orgId: input.orgId,\n factoryProjectId: input.factoryProjectId,\n workItemId: relatedItem?.id ?? null,\n ingress: { identity: ingressId, triggerType: 'linear.issueObserved' },\n configVersion: this.options.configVersion,\n expectedRevision: relatedItem?.revision ?? null,\n actor,\n outcome,\n decisions,\n causalChain: [],\n now: new Date(),\n });\n return committed.status;\n }\n}\n\nexport function attachLinearRules(\n linear: { readonly rules: LinearEventRules },\n context: IntegrationContext,\n): ((input: LinearRulesIngress) => Promise<unknown>) | undefined {\n if (!context.runtime) return undefined;\n const rules = new LinearRules({\n projects: context.storage.projects,\n storage: context.runtime.workItems,\n configVersion: context.runtime.configVersion,\n boards: context.runtime.boards,\n linearRules: linear.rules,\n });\n return input => rules.ingest(input);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../src/integrations/platform/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,wBAAgB,8BAA8B,IAAI,uBAAuB,CAaxE;AAMD,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAE,MAAM,GAAG,IAAW;CAMrF;AAED,qBAAa,iBAAiB;;gBAKhB,MAAM,EAAE,uBAAuB;IAUrC,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GACxD,OAAO,CAAC,CAAC,CAAC;IAkBP,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA0EzG;AAkBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvF;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAExF"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../src/integrations/platform/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAQD,wBAAgB,8BAA8B,IAAI,uBAAuB,CAiBxE;AAuBD,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAE,MAAM,GAAG,IAAW;CAMrF;AAED,qBAAa,iBAAiB;;gBAKhB,MAAM,EAAE,uBAAuB;IAUrC,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GACxD,OAAO,CAAC,CAAC,CAAC;IAkBP,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA0EzG;AAkBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvF;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAExF"}
@@ -1,15 +1,36 @@
1
1
  //#region src/integrations/platform/api-client.ts
2
+ const DEFAULT_INTEGRATIONS_URL = "https://integrations.mastra.ai";
3
+ const REGIONAL_INTEGRATIONS_URLS = {
4
+ us: "https://integrations.us.mastra.ai",
5
+ eu: "https://integrations.eu.mastra.ai"
6
+ };
2
7
  function platformApiClientConfigFromEnv() {
3
- const sharedApiUrl = process.env.MASTRA_SHARED_API_URL?.trim() || "https://platform.mastra.ai/v1";
8
+ const integrationsApiUrl = process.env.MASTRA_INTEGRATIONS_API_URL?.trim() || resolveIntegrationsUrl();
4
9
  const accessToken = process.env.MASTRA_PLATFORM_ACCESS_TOKEN?.trim() || process.env.MASTRA_PLATFORM_SECRET_KEY?.trim();
5
10
  if (!accessToken) throw new Error("Platform integration: missing required environment variable MASTRA_PLATFORM_ACCESS_TOKEN (or MASTRA_PLATFORM_SECRET_KEY).");
6
11
  return {
7
- baseUrl: normalizeSharedApiUrl(sharedApiUrl),
12
+ baseUrl: normalizeIntegrationsApiUrl(integrationsApiUrl),
8
13
  accessToken
9
14
  };
10
15
  }
11
- function normalizeSharedApiUrl(sharedApiUrl) {
12
- return sharedApiUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
16
+ /**
17
+ * Resolves the integrations API base URL from `MASTRA_PLATFORM_REGION`
18
+ * (case-insensitive `us` or `eu`), falling back to the global default.
19
+ * Unknown region values fall through to the global default.
20
+ */
21
+ function resolveIntegrationsUrl() {
22
+ const region = process.env.MASTRA_PLATFORM_REGION?.trim().toLowerCase();
23
+ if (region === "us" || region === "eu") return REGIONAL_INTEGRATIONS_URLS[region];
24
+ return DEFAULT_INTEGRATIONS_URL;
25
+ }
26
+ /**
27
+ * Normalizes an integrations API URL to a bare origin. Callers pass fully
28
+ * versioned paths (`/v1/server/...`, `/v2/...`), so a trailing `/v1` — as in
29
+ * legacy platform API URLs like `https://platform.mastra.ai/v1` — is stripped
30
+ * to avoid duplicated version segments.
31
+ */
32
+ function normalizeIntegrationsApiUrl(integrationsApiUrl) {
33
+ return integrationsApiUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
13
34
  }
14
35
  var PlatformApiError = class extends Error {
15
36
  status;
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","names":["#baseUrl","#accessToken","#fetch","#send"],"sources":["../../../src/integrations/platform/api-client.ts"],"sourcesContent":["export interface PlatformApiClientConfig {\n baseUrl: string;\n accessToken: string;\n fetchImpl?: typeof fetch;\n}\n\nexport function platformApiClientConfigFromEnv(): PlatformApiClientConfig {\n const sharedApiUrl = process.env.MASTRA_SHARED_API_URL?.trim() || 'https://platform.mastra.ai/v1';\n // MASTRA_PLATFORM_ACCESS_TOKEN is the credential Mastra Platform injects\n // into deployed projects; MASTRA_PLATFORM_SECRET_KEY is the org secret key\n // written by project scaffolding. The platform API accepts both forms.\n const accessToken =\n process.env.MASTRA_PLATFORM_ACCESS_TOKEN?.trim() || process.env.MASTRA_PLATFORM_SECRET_KEY?.trim();\n if (!accessToken) {\n throw new Error(\n 'Platform integration: missing required environment variable MASTRA_PLATFORM_ACCESS_TOKEN (or MASTRA_PLATFORM_SECRET_KEY).',\n );\n }\n return { baseUrl: normalizeSharedApiUrl(sharedApiUrl), accessToken };\n}\n\nfunction normalizeSharedApiUrl(sharedApiUrl: string): string {\n return sharedApiUrl.replace(/\\/+$/, '').replace(/\\/v1$/, '');\n}\n\nexport class PlatformApiError extends Error {\n readonly status: number;\n readonly retryAfterSeconds: number | null;\n\n constructor(message: string, status: number, retryAfterSeconds: number | null = null) {\n super(message);\n this.name = 'PlatformApiError';\n this.status = status;\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\nexport class PlatformApiClient {\n readonly #baseUrl: string;\n readonly #accessToken: string;\n readonly #fetch: typeof fetch;\n\n constructor(config: PlatformApiClientConfig) {\n const missing = ['baseUrl', 'accessToken'].filter(field => !config[field as keyof PlatformApiClientConfig]);\n if (missing.length > 0) {\n throw new Error(`Platform integration: missing required config field(s): ${missing.join(', ')}.`);\n }\n this.#baseUrl = config.baseUrl.replace(/\\/+$/, '');\n this.#accessToken = config.accessToken;\n this.#fetch = config.fetchImpl ?? globalThis.fetch;\n }\n\n async request<T>(\n method: string,\n path: string,\n body?: unknown,\n options?: { signal?: AbortSignal; actingUserId?: string },\n ): Promise<T> {\n const response = await this.#send(method, path, body, options);\n if (!response.ok) {\n const message = redact(await extractError(response), this.#accessToken);\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n logPlatformError('Platform API request failed', {\n method,\n path,\n status: response.status,\n retryAfterSeconds,\n message,\n });\n throw new PlatformApiError(message, response.status, retryAfterSeconds);\n }\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n\n async requestRedirect(method: string, path: string, options?: { signal?: AbortSignal }): Promise<string> {\n const response = await this.#send(method, path, undefined, options, 'manual');\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location');\n if (location) return location;\n }\n if (!response.ok) {\n const message = redact(await extractError(response), this.#accessToken);\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n logPlatformError('Platform API redirect request failed', {\n method,\n path,\n status: response.status,\n retryAfterSeconds,\n message,\n });\n throw new PlatformApiError(message, response.status, retryAfterSeconds);\n }\n logPlatformError('Platform API request did not return a redirect', { method, path, status: response.status });\n throw new PlatformApiError('Platform API request did not return a redirect.', response.status);\n }\n\n async #send(\n method: string,\n path: string,\n body?: unknown,\n options?: { signal?: AbortSignal; actingUserId?: string },\n redirect?: RequestInit['redirect'],\n ): Promise<Response> {\n const headers: Record<string, string> = {\n accept: 'application/json',\n authorization: `Bearer ${this.#accessToken}`,\n };\n // Acting end-user for platform GitHub writes: the platform resolves this\n // user's GitHub OAuth connection (org-scoped) so issues/PRs are authored\n // by the human instead of the App bot. Ignored by older platforms.\n if (options?.actingUserId) {\n headers['x-acting-user-id'] = options.actingUserId;\n }\n const timeoutSignal = AbortSignal.timeout(15_000);\n const init: RequestInit = {\n method,\n headers,\n redirect,\n signal: options?.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal,\n };\n if (body !== undefined) {\n headers['content-type'] = 'application/json';\n init.body = JSON.stringify(body);\n }\n\n try {\n return await this.#fetch(`${this.#baseUrl}${path}`, init);\n } catch (error) {\n if (error instanceof Error && error.message.includes(this.#accessToken)) {\n const redacted = new Error(redact(error.message, this.#accessToken));\n redacted.name = error.name;\n logPlatformError('Platform API transport error', {\n method,\n path,\n name: redacted.name,\n message: redacted.message,\n });\n throw redacted;\n }\n logPlatformError('Platform API transport error', {\n method,\n path,\n name: error instanceof Error ? error.name : undefined,\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n}\n\nasync function extractError(response: Response): Promise<string> {\n try {\n const data = (await response.clone().json()) as Record<string, unknown>;\n for (const field of ['detail', 'error', 'title']) {\n if (typeof data[field] === 'string' && data[field]) return data[field];\n }\n } catch {\n // Fall through to the status-based message.\n }\n return `Platform API request failed (${response.status})`;\n}\n\nfunction redact(message: string, accessToken: string): string {\n return message.split(accessToken).join('[REDACTED]');\n}\n\nexport function logPlatformInfo(message: string, fields?: Record<string, unknown>): void {\n writePlatformLog('info', message, fields);\n}\n\nexport function logPlatformWarn(message: string, fields?: Record<string, unknown>): void {\n writePlatformLog('warn', message, fields);\n}\n\nexport function logPlatformError(message: string, fields?: Record<string, unknown>): void {\n writePlatformLog('error', message, fields);\n}\n\nfunction writePlatformLog(level: 'info' | 'warn' | 'error', message: string, fields?: Record<string, unknown>): void {\n const metadata = fields ? ` ${JSON.stringify(stripUndefined(fields))}` : '';\n process.stderr.write(`[Mastra Factory] ${level.toUpperCase()} ${message}${metadata}\\n`);\n}\n\nfunction stripUndefined(fields: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));\n}\n\nfunction parseRetryAfter(value: string | null): number | null {\n if (!value) return null;\n const seconds = Number.parseInt(value, 10);\n return Number.isSafeInteger(seconds) && seconds >= 0 ? seconds : null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"api-client.js","names":["#baseUrl","#accessToken","#fetch","#send"],"sources":["../../../src/integrations/platform/api-client.ts"],"sourcesContent":["export interface PlatformApiClientConfig {\n baseUrl: string;\n accessToken: string;\n fetchImpl?: typeof fetch;\n}\n\nconst DEFAULT_INTEGRATIONS_URL = 'https://integrations.mastra.ai';\nconst REGIONAL_INTEGRATIONS_URLS: Record<'us' | 'eu', string> = {\n us: 'https://integrations.us.mastra.ai',\n eu: 'https://integrations.eu.mastra.ai',\n};\n\nexport function platformApiClientConfigFromEnv(): PlatformApiClientConfig {\n // MASTRA_INTEGRATIONS_API_URL is the dedicated override for the\n // integrations service and takes precedence over MASTRA_PLATFORM_REGION.\n // MASTRA_SHARED_API_URL is deliberately not consulted: it configures the\n // shared platform API, and integrations routing is independent of it.\n const integrationsApiUrl = process.env.MASTRA_INTEGRATIONS_API_URL?.trim() || resolveIntegrationsUrl();\n // MASTRA_PLATFORM_ACCESS_TOKEN is the credential Mastra Platform injects\n // into deployed projects; MASTRA_PLATFORM_SECRET_KEY is the org secret key\n // written by project scaffolding. The platform API accepts both forms.\n const accessToken =\n process.env.MASTRA_PLATFORM_ACCESS_TOKEN?.trim() || process.env.MASTRA_PLATFORM_SECRET_KEY?.trim();\n if (!accessToken) {\n throw new Error(\n 'Platform integration: missing required environment variable MASTRA_PLATFORM_ACCESS_TOKEN (or MASTRA_PLATFORM_SECRET_KEY).',\n );\n }\n return { baseUrl: normalizeIntegrationsApiUrl(integrationsApiUrl), accessToken };\n}\n\n/**\n * Resolves the integrations API base URL from `MASTRA_PLATFORM_REGION`\n * (case-insensitive `us` or `eu`), falling back to the global default.\n * Unknown region values fall through to the global default.\n */\nfunction resolveIntegrationsUrl(): string {\n const region = process.env.MASTRA_PLATFORM_REGION?.trim().toLowerCase();\n if (region === 'us' || region === 'eu') return REGIONAL_INTEGRATIONS_URLS[region];\n return DEFAULT_INTEGRATIONS_URL;\n}\n\n/**\n * Normalizes an integrations API URL to a bare origin. Callers pass fully\n * versioned paths (`/v1/server/...`, `/v2/...`), so a trailing `/v1` — as in\n * legacy platform API URLs like `https://platform.mastra.ai/v1` — is stripped\n * to avoid duplicated version segments.\n */\nfunction normalizeIntegrationsApiUrl(integrationsApiUrl: string): string {\n return integrationsApiUrl.replace(/\\/+$/, '').replace(/\\/v1$/, '');\n}\n\nexport class PlatformApiError extends Error {\n readonly status: number;\n readonly retryAfterSeconds: number | null;\n\n constructor(message: string, status: number, retryAfterSeconds: number | null = null) {\n super(message);\n this.name = 'PlatformApiError';\n this.status = status;\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\nexport class PlatformApiClient {\n readonly #baseUrl: string;\n readonly #accessToken: string;\n readonly #fetch: typeof fetch;\n\n constructor(config: PlatformApiClientConfig) {\n const missing = ['baseUrl', 'accessToken'].filter(field => !config[field as keyof PlatformApiClientConfig]);\n if (missing.length > 0) {\n throw new Error(`Platform integration: missing required config field(s): ${missing.join(', ')}.`);\n }\n this.#baseUrl = config.baseUrl.replace(/\\/+$/, '');\n this.#accessToken = config.accessToken;\n this.#fetch = config.fetchImpl ?? globalThis.fetch;\n }\n\n async request<T>(\n method: string,\n path: string,\n body?: unknown,\n options?: { signal?: AbortSignal; actingUserId?: string },\n ): Promise<T> {\n const response = await this.#send(method, path, body, options);\n if (!response.ok) {\n const message = redact(await extractError(response), this.#accessToken);\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n logPlatformError('Platform API request failed', {\n method,\n path,\n status: response.status,\n retryAfterSeconds,\n message,\n });\n throw new PlatformApiError(message, response.status, retryAfterSeconds);\n }\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n\n async requestRedirect(method: string, path: string, options?: { signal?: AbortSignal }): Promise<string> {\n const response = await this.#send(method, path, undefined, options, 'manual');\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location');\n if (location) return location;\n }\n if (!response.ok) {\n const message = redact(await extractError(response), this.#accessToken);\n const retryAfterSeconds = parseRetryAfter(response.headers.get('retry-after'));\n logPlatformError('Platform API redirect request failed', {\n method,\n path,\n status: response.status,\n retryAfterSeconds,\n message,\n });\n throw new PlatformApiError(message, response.status, retryAfterSeconds);\n }\n logPlatformError('Platform API request did not return a redirect', { method, path, status: response.status });\n throw new PlatformApiError('Platform API request did not return a redirect.', response.status);\n }\n\n async #send(\n method: string,\n path: string,\n body?: unknown,\n options?: { signal?: AbortSignal; actingUserId?: string },\n redirect?: RequestInit['redirect'],\n ): Promise<Response> {\n const headers: Record<string, string> = {\n accept: 'application/json',\n authorization: `Bearer ${this.#accessToken}`,\n };\n // Acting end-user for platform GitHub writes: the platform resolves this\n // user's GitHub OAuth connection (org-scoped) so issues/PRs are authored\n // by the human instead of the App bot. Ignored by older platforms.\n if (options?.actingUserId) {\n headers['x-acting-user-id'] = options.actingUserId;\n }\n const timeoutSignal = AbortSignal.timeout(15_000);\n const init: RequestInit = {\n method,\n headers,\n redirect,\n signal: options?.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal,\n };\n if (body !== undefined) {\n headers['content-type'] = 'application/json';\n init.body = JSON.stringify(body);\n }\n\n try {\n return await this.#fetch(`${this.#baseUrl}${path}`, init);\n } catch (error) {\n if (error instanceof Error && error.message.includes(this.#accessToken)) {\n const redacted = new Error(redact(error.message, this.#accessToken));\n redacted.name = error.name;\n logPlatformError('Platform API transport error', {\n method,\n path,\n name: redacted.name,\n message: redacted.message,\n });\n throw redacted;\n }\n logPlatformError('Platform API transport error', {\n method,\n path,\n name: error instanceof Error ? error.name : undefined,\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n}\n\nasync function extractError(response: Response): Promise<string> {\n try {\n const data = (await response.clone().json()) as Record<string, unknown>;\n for (const field of ['detail', 'error', 'title']) {\n if (typeof data[field] === 'string' && data[field]) return data[field];\n }\n } catch {\n // Fall through to the status-based message.\n }\n return `Platform API request failed (${response.status})`;\n}\n\nfunction redact(message: string, accessToken: string): string {\n return message.split(accessToken).join('[REDACTED]');\n}\n\nexport function logPlatformInfo(message: string, fields?: Record<string, unknown>): void {\n writePlatformLog('info', message, fields);\n}\n\nexport function logPlatformWarn(message: string, fields?: Record<string, unknown>): void {\n writePlatformLog('warn', message, fields);\n}\n\nexport function logPlatformError(message: string, fields?: Record<string, unknown>): void {\n writePlatformLog('error', message, fields);\n}\n\nfunction writePlatformLog(level: 'info' | 'warn' | 'error', message: string, fields?: Record<string, unknown>): void {\n const metadata = fields ? ` ${JSON.stringify(stripUndefined(fields))}` : '';\n process.stderr.write(`[Mastra Factory] ${level.toUpperCase()} ${message}${metadata}\\n`);\n}\n\nfunction stripUndefined(fields: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));\n}\n\nfunction parseRetryAfter(value: string | null): number | null {\n if (!value) return null;\n const seconds = Number.parseInt(value, 10);\n return Number.isSafeInteger(seconds) && seconds >= 0 ? seconds : null;\n}\n"],"mappings":"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"}
@@ -75,6 +75,7 @@ export declare class PlatformGithubIntegration implements FactoryIntegration {
75
75
  listInstallationRepos(installationId: number): Promise<RepoSummary[]>;
76
76
  mintInstallationToken(installationId: number): Promise<string>;
77
77
  addIssueLabels(_installationId: number, sourceId: string, issueNumber: number, labels: string[]): Promise<string[]>;
78
+ removeIssueLabel(_installationId: number, sourceId: string, issueNumber: number, label: string): Promise<void>;
78
79
  getInstallationOctokit(_installationId: number): ReturnType<GithubIntegration['getInstallationOctokit']>;
79
80
  }
80
81
  //# sourceMappingURL=integration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../../src/integrations/platform/github/integration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../../src/integrations/platform/github/integration.ts"],"names":[],"mappings":"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"}
@@ -737,6 +737,11 @@ var PlatformGithubIntegration = class {
737
737
  async addIssueLabels(_installationId, sourceId, issueNumber, labels) {
738
738
  return (await this.#client.request("POST", repositoryPath(sourceId, `issues/${issueNumber}/labels`), { labels })).labels;
739
739
  }
740
+ async removeIssueLabel(_installationId, sourceId, issueNumber, label) {
741
+ const name = label.trim();
742
+ if (!name) return;
743
+ await this.#client.request("DELETE", repositoryPath(sourceId, `issues/${issueNumber}/labels/${encodeURIComponent(name)}`));
744
+ }
740
745
  getInstallationOctokit(_installationId) {
741
746
  return { pulls: { get: async ({ owner, repo, pull_number }) => {
742
747
  return { data: { base: { repo: { id: (await this.#client.request("GET", repositoryPath(`${owner}/${repo}`, `pulls/${pull_number}`))).base.repo.id } } } };