@rudderhq/server 0.2.5-canary.8 → 0.2.5

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 (309) hide show
  1. package/dist/bootstrap/plugin-host-runtime.d.ts +39 -39
  2. package/dist/bundled-plugins/plugin-linear/dist/worker.js +101 -147
  3. package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +2 -2
  4. package/dist/bundled-plugins/plugin-linear/package.json +1 -1
  5. package/dist/routes/access-onboarding.helpers.d.ts +142 -0
  6. package/dist/routes/access-onboarding.helpers.d.ts.map +1 -0
  7. package/dist/routes/access-onboarding.helpers.js +762 -0
  8. package/dist/routes/access-onboarding.helpers.js.map +1 -0
  9. package/dist/routes/access.d.ts +2 -48
  10. package/dist/routes/access.d.ts.map +1 -1
  11. package/dist/routes/access.helpers.d.ts +109 -0
  12. package/dist/routes/access.helpers.d.ts.map +1 -0
  13. package/dist/routes/access.helpers.js +460 -0
  14. package/dist/routes/access.helpers.js.map +1 -0
  15. package/dist/routes/access.js +6 -1218
  16. package/dist/routes/access.js.map +1 -1
  17. package/dist/routes/agents.d.ts.map +1 -1
  18. package/dist/routes/agents.js +55 -1057
  19. package/dist/routes/agents.js.map +1 -1
  20. package/dist/routes/agents.management-routes.d.ts +12 -0
  21. package/dist/routes/agents.management-routes.d.ts.map +1 -0
  22. package/dist/routes/agents.management-routes.js +1067 -0
  23. package/dist/routes/agents.management-routes.js.map +1 -0
  24. package/dist/routes/chats.d.ts.map +1 -1
  25. package/dist/routes/chats.js +42 -652
  26. package/dist/routes/chats.js.map +1 -1
  27. package/dist/routes/chats.stream-routes.d.ts +12 -0
  28. package/dist/routes/chats.stream-routes.d.ts.map +1 -0
  29. package/dist/routes/chats.stream-routes.js +666 -0
  30. package/dist/routes/chats.stream-routes.js.map +1 -0
  31. package/dist/routes/issues.comments-attachments.d.ts +12 -0
  32. package/dist/routes/issues.comments-attachments.d.ts.map +1 -0
  33. package/dist/routes/issues.comments-attachments.js +511 -0
  34. package/dist/routes/issues.comments-attachments.js.map +1 -0
  35. package/dist/routes/issues.d.ts.map +1 -1
  36. package/dist/routes/issues.js +43 -1128
  37. package/dist/routes/issues.js.map +1 -1
  38. package/dist/routes/issues.mutations.d.ts +12 -0
  39. package/dist/routes/issues.mutations.d.ts.map +1 -0
  40. package/dist/routes/issues.mutations.js +635 -0
  41. package/dist/routes/issues.mutations.js.map +1 -0
  42. package/dist/routes/plugins.d.ts.map +1 -1
  43. package/dist/routes/plugins.js +14 -694
  44. package/dist/routes/plugins.js.map +1 -1
  45. package/dist/routes/plugins.operations-routes.d.ts +28 -0
  46. package/dist/routes/plugins.operations-routes.d.ts.map +1 -0
  47. package/dist/routes/plugins.operations-routes.js +720 -0
  48. package/dist/routes/plugins.operations-routes.js.map +1 -0
  49. package/dist/services/access.d.ts +21 -21
  50. package/dist/services/activity.d.ts +19 -19
  51. package/dist/services/agents.d.ts +158 -158
  52. package/dist/services/approvals.d.ts +29 -29
  53. package/dist/services/assets.d.ts +8 -8
  54. package/dist/services/automations.d.ts +41 -27
  55. package/dist/services/automations.d.ts.map +1 -1
  56. package/dist/services/automations.js +287 -110
  57. package/dist/services/automations.js.map +1 -1
  58. package/dist/services/automations.scheduler.d.ts +9 -0
  59. package/dist/services/automations.scheduler.d.ts.map +1 -0
  60. package/dist/services/automations.scheduler.js +101 -0
  61. package/dist/services/automations.scheduler.js.map +1 -0
  62. package/dist/services/board-auth.d.ts +32 -32
  63. package/dist/services/calendar.d.ts +26 -26
  64. package/dist/services/chat-assistant.d.ts +3 -47
  65. package/dist/services/chat-assistant.d.ts.map +1 -1
  66. package/dist/services/chat-assistant.helpers.d.ts +156 -0
  67. package/dist/services/chat-assistant.helpers.d.ts.map +1 -0
  68. package/dist/services/chat-assistant.helpers.js +862 -0
  69. package/dist/services/chat-assistant.helpers.js.map +1 -0
  70. package/dist/services/chat-assistant.js +2 -861
  71. package/dist/services/chat-assistant.js.map +1 -1
  72. package/dist/services/chats.d.ts +149 -247
  73. package/dist/services/chats.d.ts.map +1 -1
  74. package/dist/services/chats.helpers.d.ts +117 -0
  75. package/dist/services/chats.helpers.d.ts.map +1 -0
  76. package/dist/services/chats.helpers.js +285 -0
  77. package/dist/services/chats.helpers.js.map +1 -0
  78. package/dist/services/chats.js +6 -286
  79. package/dist/services/chats.js.map +1 -1
  80. package/dist/services/costs.d.ts +8 -8
  81. package/dist/services/finance.d.ts +18 -18
  82. package/dist/services/goals.d.ts +30 -30
  83. package/dist/services/heartbeat.d.ts +3 -1
  84. package/dist/services/heartbeat.d.ts.map +1 -1
  85. package/dist/services/heartbeat.js +3 -1
  86. package/dist/services/heartbeat.js.map +1 -1
  87. package/dist/services/issue-approvals.d.ts +4 -4
  88. package/dist/services/issue-review-wakeup.d.ts +3 -3
  89. package/dist/services/issues.comments-attachments.d.ts +141 -0
  90. package/dist/services/issues.comments-attachments.d.ts.map +1 -0
  91. package/dist/services/issues.comments-attachments.js +313 -0
  92. package/dist/services/issues.comments-attachments.js.map +1 -0
  93. package/dist/services/issues.d.ts +205 -256
  94. package/dist/services/issues.d.ts.map +1 -1
  95. package/dist/services/issues.helpers.d.ts +87 -0
  96. package/dist/services/issues.helpers.d.ts.map +1 -0
  97. package/dist/services/issues.helpers.js +270 -0
  98. package/dist/services/issues.helpers.js.map +1 -0
  99. package/dist/services/issues.js +5 -569
  100. package/dist/services/issues.js.map +1 -1
  101. package/dist/services/knowledge-portability/organization-portability.core.d.ts +210 -0
  102. package/dist/services/knowledge-portability/organization-portability.core.d.ts.map +1 -0
  103. package/dist/services/knowledge-portability/organization-portability.core.js +997 -0
  104. package/dist/services/knowledge-portability/organization-portability.core.js.map +1 -0
  105. package/dist/services/knowledge-portability/organization-portability.d.ts +6 -28
  106. package/dist/services/knowledge-portability/organization-portability.d.ts.map +1 -1
  107. package/dist/services/knowledge-portability/organization-portability.export.d.ts +24 -0
  108. package/dist/services/knowledge-portability/organization-portability.export.d.ts.map +1 -0
  109. package/dist/services/knowledge-portability/organization-portability.export.js +607 -0
  110. package/dist/services/knowledge-portability/organization-portability.export.js.map +1 -0
  111. package/dist/services/knowledge-portability/organization-portability.files.d.ts +69 -0
  112. package/dist/services/knowledge-portability/organization-portability.files.d.ts.map +1 -0
  113. package/dist/services/knowledge-portability/organization-portability.files.js +597 -0
  114. package/dist/services/knowledge-portability/organization-portability.files.js.map +1 -0
  115. package/dist/services/knowledge-portability/organization-portability.import.d.ts +31 -0
  116. package/dist/services/knowledge-portability/organization-portability.import.d.ts.map +1 -0
  117. package/dist/services/knowledge-portability/organization-portability.import.js +575 -0
  118. package/dist/services/knowledge-portability/organization-portability.import.js.map +1 -0
  119. package/dist/services/knowledge-portability/organization-portability.js +37 -3848
  120. package/dist/services/knowledge-portability/organization-portability.js.map +1 -1
  121. package/dist/services/knowledge-portability/organization-portability.package.d.ts +72 -0
  122. package/dist/services/knowledge-portability/organization-portability.package.d.ts.map +1 -0
  123. package/dist/services/knowledge-portability/organization-portability.package.js +749 -0
  124. package/dist/services/knowledge-portability/organization-portability.package.js.map +1 -0
  125. package/dist/services/knowledge-portability/organization-portability.preview.d.ts +18 -0
  126. package/dist/services/knowledge-portability/organization-portability.preview.d.ts.map +1 -0
  127. package/dist/services/knowledge-portability/organization-portability.preview.js +333 -0
  128. package/dist/services/knowledge-portability/organization-portability.preview.js.map +1 -0
  129. package/dist/services/knowledge-portability/organization-portability.resolve-source.d.ts +4 -0
  130. package/dist/services/knowledge-portability/organization-portability.resolve-source.d.ts.map +1 -0
  131. package/dist/services/knowledge-portability/organization-portability.resolve-source.js +86 -0
  132. package/dist/services/knowledge-portability/organization-portability.resolve-source.js.map +1 -0
  133. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts +221 -0
  134. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts.map +1 -0
  135. package/dist/services/knowledge-portability/organization-skills.catalog.js +999 -0
  136. package/dist/services/knowledge-portability/organization-skills.catalog.js.map +1 -0
  137. package/dist/services/knowledge-portability/organization-skills.d.ts +4 -75
  138. package/dist/services/knowledge-portability/organization-skills.d.ts.map +1 -1
  139. package/dist/services/knowledge-portability/organization-skills.js +11 -2008
  140. package/dist/services/knowledge-portability/organization-skills.js.map +1 -1
  141. package/dist/services/knowledge-portability/organization-skills.scans.d.ts +16 -0
  142. package/dist/services/knowledge-portability/organization-skills.scans.d.ts.map +1 -0
  143. package/dist/services/knowledge-portability/organization-skills.scans.js +300 -0
  144. package/dist/services/knowledge-portability/organization-skills.scans.js.map +1 -0
  145. package/dist/services/knowledge-portability/organization-skills.sources.d.ts +68 -0
  146. package/dist/services/knowledge-portability/organization-skills.sources.d.ts.map +1 -0
  147. package/dist/services/knowledge-portability/organization-skills.sources.js +728 -0
  148. package/dist/services/knowledge-portability/organization-skills.sources.js.map +1 -0
  149. package/dist/services/messenger.d.ts +2 -2
  150. package/dist/services/messenger.js +2 -2
  151. package/dist/services/messenger.js.map +1 -1
  152. package/dist/services/organization-skills.d.ts +3 -1
  153. package/dist/services/organization-skills.d.ts.map +1 -1
  154. package/dist/services/organization-skills.js +3 -1
  155. package/dist/services/organization-skills.js.map +1 -1
  156. package/dist/services/orgs.d.ts +9 -9
  157. package/dist/services/plugin-loader.core.d.ts +14 -0
  158. package/dist/services/plugin-loader.core.d.ts.map +1 -0
  159. package/dist/services/plugin-loader.core.js +905 -0
  160. package/dist/services/plugin-loader.core.js.map +1 -0
  161. package/dist/services/plugin-loader.d.ts +3 -440
  162. package/dist/services/plugin-loader.d.ts.map +1 -1
  163. package/dist/services/plugin-loader.helpers.d.ts +468 -0
  164. package/dist/services/plugin-loader.helpers.d.ts.map +1 -0
  165. package/dist/services/plugin-loader.helpers.js +263 -0
  166. package/dist/services/plugin-loader.helpers.js.map +1 -0
  167. package/dist/services/plugin-loader.js +3 -1191
  168. package/dist/services/plugin-loader.js.map +1 -1
  169. package/dist/services/plugin-loader.worker-paths.d.ts +7 -0
  170. package/dist/services/plugin-loader.worker-paths.d.ts.map +1 -0
  171. package/dist/services/plugin-loader.worker-paths.js +85 -0
  172. package/dist/services/plugin-loader.worker-paths.js.map +1 -0
  173. package/dist/services/plugin-registry.d.ts +123 -123
  174. package/dist/services/projects.d.ts +8 -8
  175. package/dist/services/runtime-kernel/heartbeat.core.d.ts +725 -0
  176. package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -0
  177. package/dist/services/runtime-kernel/heartbeat.core.js +525 -0
  178. package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -0
  179. package/dist/services/runtime-kernel/heartbeat.d.ts +38 -259
  180. package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
  181. package/dist/services/runtime-kernel/heartbeat.execute.d.ts +5 -0
  182. package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -0
  183. package/dist/services/runtime-kernel/heartbeat.execute.js +1052 -0
  184. package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -0
  185. package/dist/services/runtime-kernel/heartbeat.js +50 -4142
  186. package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
  187. package/dist/services/runtime-kernel/heartbeat.misc.d.ts +30 -0
  188. package/dist/services/runtime-kernel/heartbeat.misc.d.ts.map +1 -0
  189. package/dist/services/runtime-kernel/heartbeat.misc.js +483 -0
  190. package/dist/services/runtime-kernel/heartbeat.misc.js.map +1 -0
  191. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts +38 -0
  192. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts.map +1 -0
  193. package/dist/services/runtime-kernel/heartbeat.recovery.js +605 -0
  194. package/dist/services/runtime-kernel/heartbeat.recovery.js.map +1 -0
  195. package/dist/services/runtime-kernel/heartbeat.release.d.ts +6 -0
  196. package/dist/services/runtime-kernel/heartbeat.release.d.ts.map +1 -0
  197. package/dist/services/runtime-kernel/heartbeat.release.js +398 -0
  198. package/dist/services/runtime-kernel/heartbeat.release.js.map +1 -0
  199. package/dist/services/runtime-kernel/heartbeat.sessions.d.ts +229 -0
  200. package/dist/services/runtime-kernel/heartbeat.sessions.d.ts.map +1 -0
  201. package/dist/services/runtime-kernel/heartbeat.sessions.js +708 -0
  202. package/dist/services/runtime-kernel/heartbeat.sessions.js.map +1 -0
  203. package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts +5 -0
  204. package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts.map +1 -0
  205. package/dist/services/runtime-kernel/heartbeat.wakeup.js +552 -0
  206. package/dist/services/runtime-kernel/heartbeat.wakeup.js.map +1 -0
  207. package/dist/services/secrets.d.ts +25 -25
  208. package/dist/services/sidebar-badges.js +1 -1
  209. package/dist/services/sidebar-badges.js.map +1 -1
  210. package/dist/services/workspace-runtime.comments.d.ts +6 -0
  211. package/dist/services/workspace-runtime.comments.d.ts.map +1 -0
  212. package/dist/services/workspace-runtime.comments.js +17 -0
  213. package/dist/services/workspace-runtime.comments.js.map +1 -0
  214. package/dist/services/workspace-runtime.d.ts +4 -163
  215. package/dist/services/workspace-runtime.d.ts.map +1 -1
  216. package/dist/services/workspace-runtime.helpers.d.ts +163 -0
  217. package/dist/services/workspace-runtime.helpers.d.ts.map +1 -0
  218. package/dist/services/workspace-runtime.helpers.js +360 -0
  219. package/dist/services/workspace-runtime.helpers.js.map +1 -0
  220. package/dist/services/workspace-runtime.js +4 -1236
  221. package/dist/services/workspace-runtime.js.map +1 -1
  222. package/dist/services/workspace-runtime.lifecycle.d.ts +35 -0
  223. package/dist/services/workspace-runtime.lifecycle.d.ts.map +1 -0
  224. package/dist/services/workspace-runtime.lifecycle.js +266 -0
  225. package/dist/services/workspace-runtime.lifecycle.js.map +1 -0
  226. package/dist/services/workspace-runtime.services.d.ts +140 -0
  227. package/dist/services/workspace-runtime.services.d.ts.map +1 -0
  228. package/dist/services/workspace-runtime.services.js +606 -0
  229. package/dist/services/workspace-runtime.services.js.map +1 -0
  230. package/package.json +21 -15
  231. package/ui-dist/assets/{_basePickBy-DeCw-kw3.js → _basePickBy-N8I9ml5Y.js} +1 -1
  232. package/ui-dist/assets/{_baseUniq-CVepsVZm.js → _baseUniq-BuSlpRSQ.js} +1 -1
  233. package/ui-dist/assets/{arc-QifRrkx2.js → arc-qX-dPyA1.js} +1 -1
  234. package/ui-dist/assets/{architectureDiagram-2XIMDMQ5-CT4me0hw.js → architectureDiagram-2XIMDMQ5-DhjkbXsp.js} +1 -1
  235. package/ui-dist/assets/{blockDiagram-WCTKOSBZ-uD6J91MI.js → blockDiagram-WCTKOSBZ-JS-tTu3J.js} +1 -1
  236. package/ui-dist/assets/{c4Diagram-IC4MRINW-D2GM2pzG.js → c4Diagram-IC4MRINW-4DqwCWIx.js} +1 -1
  237. package/ui-dist/assets/channel-CccCW5_a.js +1 -0
  238. package/ui-dist/assets/{chunk-4BX2VUAB-D8pPrlss.js → chunk-4BX2VUAB-T37SqBpp.js} +1 -1
  239. package/ui-dist/assets/{chunk-55IACEB6-CHF68vwj.js → chunk-55IACEB6-BSj9hdqK.js} +1 -1
  240. package/ui-dist/assets/{chunk-FMBD7UC4-CKmGUf9X.js → chunk-FMBD7UC4-Dkrlh0Wk.js} +1 -1
  241. package/ui-dist/assets/{chunk-JSJVCQXG-CTBCV-7X.js → chunk-JSJVCQXG-C0ZE3QdB.js} +1 -1
  242. package/ui-dist/assets/{chunk-KX2RTZJC-DV5XzGob.js → chunk-KX2RTZJC-DOZQM9gW.js} +1 -1
  243. package/ui-dist/assets/{chunk-NQ4KR5QH-B7diT0e4.js → chunk-NQ4KR5QH-5Yr3U2k8.js} +1 -1
  244. package/ui-dist/assets/{chunk-QZHKN3VN-BphcSb1i.js → chunk-QZHKN3VN-CvKTufwF.js} +1 -1
  245. package/ui-dist/assets/{chunk-WL4C6EOR-Bs_jQBMG.js → chunk-WL4C6EOR-IoEM0jyx.js} +1 -1
  246. package/ui-dist/assets/classDiagram-VBA2DB6C-JKk4tCW2.js +1 -0
  247. package/ui-dist/assets/classDiagram-v2-RAHNMMFH-JKk4tCW2.js +1 -0
  248. package/ui-dist/assets/clone-Onaweg8D.js +1 -0
  249. package/ui-dist/assets/{cose-bilkent-S5V4N54A-BxfO0pV9.js → cose-bilkent-S5V4N54A-CTvr1OFj.js} +1 -1
  250. package/ui-dist/assets/{dagre-KLK3FWXG-BiDkAX-Z.js → dagre-KLK3FWXG-UZ-SNjVK.js} +1 -1
  251. package/ui-dist/assets/{diagram-E7M64L7V-Btz_oxkC.js → diagram-E7M64L7V-D7RAN0Hr.js} +1 -1
  252. package/ui-dist/assets/{diagram-IFDJBPK2-Cdp8lQxJ.js → diagram-IFDJBPK2-B4LViaFR.js} +1 -1
  253. package/ui-dist/assets/{diagram-P4PSJMXO-DuTbeAS1.js → diagram-P4PSJMXO-CY1be7ak.js} +1 -1
  254. package/ui-dist/assets/{erDiagram-INFDFZHY-CzoQlOwo.js → erDiagram-INFDFZHY-Dca0KkvJ.js} +1 -1
  255. package/ui-dist/assets/{flowDiagram-PKNHOUZH-Diz_MWi3.js → flowDiagram-PKNHOUZH-i-qMvfwg.js} +1 -1
  256. package/ui-dist/assets/{ganttDiagram-A5KZAMGK-CWeGI1E-.js → ganttDiagram-A5KZAMGK-Wxq2lhbh.js} +1 -1
  257. package/ui-dist/assets/{gitGraphDiagram-K3NZZRJ6-C3QhZnAN.js → gitGraphDiagram-K3NZZRJ6-DwzgPlAY.js} +1 -1
  258. package/ui-dist/assets/{graph-KQH4eaLv.js → graph-BAqf89Tz.js} +1 -1
  259. package/ui-dist/assets/{index-CkEEsJ_9.js → index-4eCzaLuY.js} +1 -1
  260. package/ui-dist/assets/{index-DCOA92Vt.js → index-8uu-nKqK.js} +1 -1
  261. package/ui-dist/assets/{index-DtsZnqcf.js → index-B-1NEcI_.js} +1 -1
  262. package/ui-dist/assets/{index-BvGpil9e.js → index-B0b_3Eu5.js} +1 -1
  263. package/ui-dist/assets/{index-BMhxh9sB.js → index-B8v0eZjP.js} +1 -1
  264. package/ui-dist/assets/{index-aKvEm2pJ.js → index-BN7Moj3u.js} +1 -1
  265. package/ui-dist/assets/{index-iJyjaIGd.js → index-BSpxh3cY.js} +1 -1
  266. package/ui-dist/assets/{index-DhRKQjzu.js → index-BY44RIi9.js} +1 -1
  267. package/ui-dist/assets/{index-Z4rTzdcL.js → index-BhyQJhdZ.js} +1 -1
  268. package/ui-dist/assets/{index-DBxBUiZC.js → index-BkPL_iGU.js} +1 -1
  269. package/ui-dist/assets/{index-CsSppW5U.js → index-BsPfoHXS.js} +1 -1
  270. package/ui-dist/assets/{index-B8J1oewY.js → index-BstW7nmv.js} +1 -1
  271. package/ui-dist/assets/{index-CVZYu_kq.js → index-BwB67Zyz.js} +1 -1
  272. package/ui-dist/assets/index-C2peSkmT.css +1 -0
  273. package/ui-dist/assets/{index-Djz3PL1M.js → index-C3ktOsS_.js} +1 -1
  274. package/ui-dist/assets/{index-BMZfWLwr.js → index-CMyABlS-.js} +1 -1
  275. package/ui-dist/assets/{index-Cqdw7Lnc.js → index-CyBJ8ujC.js} +1 -1
  276. package/ui-dist/assets/{index-Ctp_0y5X.js → index-DAxM2W3O.js} +1 -1
  277. package/ui-dist/assets/{index-_jGthZ-1.js → index-DVZXPmhk.js} +1 -1
  278. package/ui-dist/assets/{index-CBLnbZVL.js → index-Dc19uAyw.js} +1 -1
  279. package/ui-dist/assets/index-DzHrwZu1.js +1511 -0
  280. package/ui-dist/assets/{index-ChTjk1gO.js → index-LJuf53Ye.js} +1 -1
  281. package/ui-dist/assets/{index-wXEAD8rI.js → index-Ugw5VWWz.js} +1 -1
  282. package/ui-dist/assets/{index-ciyPUpT9.js → index-YGraEFR7.js} +1 -1
  283. package/ui-dist/assets/{infoDiagram-LFFYTUFH-DbMzKsuw.js → infoDiagram-LFFYTUFH-jLmDtFVR.js} +1 -1
  284. package/ui-dist/assets/{ishikawaDiagram-PHBUUO56-CcKXcf2V.js → ishikawaDiagram-PHBUUO56-6OGMyLT8.js} +1 -1
  285. package/ui-dist/assets/{journeyDiagram-4ABVD52K-BY2GuHyR.js → journeyDiagram-4ABVD52K-yQjl6E0t.js} +1 -1
  286. package/ui-dist/assets/{kanban-definition-K7BYSVSG-BlZWM0Uz.js → kanban-definition-K7BYSVSG-DkdCeQlS.js} +1 -1
  287. package/ui-dist/assets/{layout-qHGAYgRY.js → layout-CqSYvZ_w.js} +1 -1
  288. package/ui-dist/assets/{linear-BigkGXbh.js → linear-B8xGZaoi.js} +1 -1
  289. package/ui-dist/assets/{mermaid.core-DZ099nW4.js → mermaid.core-AKL_cdyk.js} +4 -4
  290. package/ui-dist/assets/{mindmap-definition-YRQLILUH-CElDqDe0.js → mindmap-definition-YRQLILUH-Zr-dXC0x.js} +1 -1
  291. package/ui-dist/assets/{pieDiagram-SKSYHLDU-I2LDYrgm.js → pieDiagram-SKSYHLDU-BvDAU-Nk.js} +1 -1
  292. package/ui-dist/assets/{quadrantDiagram-337W2JSQ-D-U35edU.js → quadrantDiagram-337W2JSQ-Dn9kM62o.js} +1 -1
  293. package/ui-dist/assets/{requirementDiagram-Z7DCOOCP-FAWtaOKe.js → requirementDiagram-Z7DCOOCP-GIsIh7Sd.js} +1 -1
  294. package/ui-dist/assets/{sankeyDiagram-WA2Y5GQK-CzFHHNNh.js → sankeyDiagram-WA2Y5GQK-CUCuBkuf.js} +1 -1
  295. package/ui-dist/assets/{sequenceDiagram-2WXFIKYE-Cy-UViPL.js → sequenceDiagram-2WXFIKYE-MDpUY2HM.js} +1 -1
  296. package/ui-dist/assets/{stateDiagram-RAJIS63D-BEdt3CLl.js → stateDiagram-RAJIS63D-BymMpuUU.js} +1 -1
  297. package/ui-dist/assets/stateDiagram-v2-FVOUBMTO-Bi2oCU6d.js +1 -0
  298. package/ui-dist/assets/{timeline-definition-YZTLITO2-YD1e-WHS.js → timeline-definition-YZTLITO2-B6ofPhhy.js} +1 -1
  299. package/ui-dist/assets/{treemap-KZPCXAKY-BnqlVkAC.js → treemap-KZPCXAKY-DnLO6w1l.js} +1 -1
  300. package/ui-dist/assets/{vennDiagram-LZ73GAT5-f4WCy3o6.js → vennDiagram-LZ73GAT5-D0MyZIDl.js} +1 -1
  301. package/ui-dist/assets/{xychartDiagram-JWTSCODW-CWA35znA.js → xychartDiagram-JWTSCODW-rADY1iUG.js} +1 -1
  302. package/ui-dist/index.html +2 -2
  303. package/ui-dist/assets/channel-BV7st2TW.js +0 -1
  304. package/ui-dist/assets/classDiagram-VBA2DB6C-Cw_xj5ie.js +0 -1
  305. package/ui-dist/assets/classDiagram-v2-RAHNMMFH-Cw_xj5ie.js +0 -1
  306. package/ui-dist/assets/clone-DGshofUt.js +0 -1
  307. package/ui-dist/assets/index-Ded0dPwB.css +0 -1
  308. package/ui-dist/assets/index-Jhxth516.js +0 -1510
  309. package/ui-dist/assets/stateDiagram-v2-FVOUBMTO-cW7aES_v.js +0 -1
@@ -0,0 +1,720 @@
1
+ /**
2
+ * @fileoverview Plugin management REST API routes
3
+ *
4
+ * This module provides Express routes for managing the complete plugin lifecycle:
5
+ * - Listing and filtering plugins by status
6
+ * - Installing plugins from npm or local paths
7
+ * - Uninstalling plugins (soft delete or hard purge)
8
+ * - Enabling/disabling plugins
9
+ * - Running health diagnostics
10
+ * - Upgrading plugins
11
+ * - Retrieving UI slot contributions for frontend rendering
12
+ * - Discovering and executing plugin-contributed agent tools
13
+ *
14
+ * All routes require board-level authentication (assertBoard middleware).
15
+ *
16
+ * @module server/routes/plugins
17
+ * @see doc/plugins/PLUGIN_SPEC.md for the full plugin specification
18
+ */
19
+ import { randomUUID } from "node:crypto";
20
+ import { and, desc, eq, gte } from "drizzle-orm";
21
+ import { pluginLogs, pluginWebhookDeliveries } from "@rudderhq/db";
22
+ import { publishGlobalLiveEvent } from "../services/live-events.js";
23
+ import { JsonRpcCallError, PLUGIN_RPC_ERROR_CODES } from "@rudderhq/plugin-sdk";
24
+ import { assertBoard } from "./authz.js";
25
+ import { validateInstanceConfig } from "../services/plugin-config-validator.js";
26
+ export function registerPluginOperationsRoutes(ctx) {
27
+ const { router, db, loader, registry, lifecycle, bridgeDeps, jobDeps, webhookDeps, resolvePlugin, logPluginMutationActivity, mapRpcErrorToBridgeError, } = ctx;
28
+ router.get("/plugins/:pluginId/logs", async (req, res) => {
29
+ assertBoard(req);
30
+ const { pluginId } = req.params;
31
+ const plugin = await resolvePlugin(registry, pluginId);
32
+ if (!plugin) {
33
+ res.status(404).json({ error: "Plugin not found" });
34
+ return;
35
+ }
36
+ const limit = Math.min(Math.max(parseInt(req.query.limit, 10) || 25, 1), 500);
37
+ const level = req.query.level;
38
+ const since = req.query.since;
39
+ const conditions = [eq(pluginLogs.pluginId, plugin.id)];
40
+ if (level) {
41
+ conditions.push(eq(pluginLogs.level, level));
42
+ }
43
+ if (since) {
44
+ const sinceDate = new Date(since);
45
+ if (!isNaN(sinceDate.getTime())) {
46
+ conditions.push(gte(pluginLogs.createdAt, sinceDate));
47
+ }
48
+ }
49
+ const rows = await db
50
+ .select()
51
+ .from(pluginLogs)
52
+ .where(and(...conditions))
53
+ .orderBy(desc(pluginLogs.createdAt))
54
+ .limit(limit);
55
+ res.json(rows);
56
+ });
57
+ /**
58
+ * POST /api/plugins/:pluginId/upgrade
59
+ *
60
+ * Upgrade a plugin to a newer version.
61
+ *
62
+ * Request body (optional):
63
+ * - version: Target version (defaults to latest)
64
+ *
65
+ * If the upgrade adds new capabilities, the plugin transitions to
66
+ * 'upgrade_pending' state for board approval. Otherwise, it goes
67
+ * directly to 'ready'.
68
+ *
69
+ * Response: PluginRecord
70
+ * Errors: 404 if plugin not found, 400 for lifecycle errors
71
+ */
72
+ router.post("/plugins/:pluginId/upgrade", async (req, res) => {
73
+ assertBoard(req);
74
+ const { pluginId } = req.params;
75
+ const body = req.body;
76
+ const version = body?.version;
77
+ const plugin = await resolvePlugin(registry, pluginId);
78
+ if (!plugin) {
79
+ res.status(404).json({ error: "Plugin not found" });
80
+ return;
81
+ }
82
+ try {
83
+ // Upgrade the plugin - this would typically:
84
+ // 1. Download the new version
85
+ // 2. Compare capabilities
86
+ // 3. If new capabilities, mark as upgrade_pending
87
+ // 4. Otherwise, transition to ready
88
+ const result = await lifecycle.upgrade(plugin.id, version);
89
+ await logPluginMutationActivity(req, "plugin.upgraded", plugin.id, {
90
+ pluginId: plugin.id,
91
+ pluginKey: plugin.pluginKey,
92
+ previousVersion: plugin.version,
93
+ version: result?.version ?? plugin.version,
94
+ targetVersion: version ?? null,
95
+ });
96
+ publishGlobalLiveEvent({ type: "plugin.ui.updated", payload: { pluginId: plugin.id, action: "upgraded" } });
97
+ res.json(result);
98
+ }
99
+ catch (err) {
100
+ const message = err instanceof Error ? err.message : String(err);
101
+ res.status(400).json({ error: message });
102
+ }
103
+ });
104
+ // ===========================================================================
105
+ // Plugin configuration routes
106
+ // ===========================================================================
107
+ /**
108
+ * GET /api/plugins/:pluginId/config
109
+ *
110
+ * Retrieve the current instance configuration for a plugin.
111
+ *
112
+ * Returns the `PluginConfig` record if one exists, or `null` if the plugin
113
+ * has not yet been configured.
114
+ *
115
+ * Response: `PluginConfig | null`
116
+ * Errors: 404 if plugin not found
117
+ */
118
+ router.get("/plugins/:pluginId/config", async (req, res) => {
119
+ assertBoard(req);
120
+ const { pluginId } = req.params;
121
+ const plugin = await resolvePlugin(registry, pluginId);
122
+ if (!plugin) {
123
+ res.status(404).json({ error: "Plugin not found" });
124
+ return;
125
+ }
126
+ const config = await registry.getConfig(plugin.id);
127
+ res.json(config);
128
+ });
129
+ /**
130
+ * POST /api/plugins/:pluginId/config
131
+ *
132
+ * Save (create or replace) the instance configuration for a plugin.
133
+ *
134
+ * The caller provides the full `configJson` object. The server persists it
135
+ * via `registry.upsertConfig()`.
136
+ *
137
+ * Request body:
138
+ * - `configJson`: Configuration values matching the plugin's `instanceConfigSchema`
139
+ *
140
+ * Response: `PluginConfig`
141
+ * Errors:
142
+ * - 400 if request validation fails
143
+ * - 404 if plugin not found
144
+ */
145
+ router.post("/plugins/:pluginId/config", async (req, res) => {
146
+ assertBoard(req);
147
+ const { pluginId } = req.params;
148
+ const plugin = await resolvePlugin(registry, pluginId);
149
+ if (!plugin) {
150
+ res.status(404).json({ error: "Plugin not found" });
151
+ return;
152
+ }
153
+ const body = req.body;
154
+ if (!body?.configJson || typeof body.configJson !== "object") {
155
+ res.status(400).json({ error: '"configJson" is required and must be an object' });
156
+ return;
157
+ }
158
+ // Strip devUiUrl unless the caller is an instance admin. devUiUrl activates
159
+ // a dev-proxy in the static file route that could be abused for SSRF if any
160
+ // board-level user were allowed to set it.
161
+ if ("devUiUrl" in body.configJson &&
162
+ !(req.actor.type === "board" && req.actor.isInstanceAdmin)) {
163
+ delete body.configJson.devUiUrl;
164
+ }
165
+ // Validate configJson against the plugin's instanceConfigSchema (if declared).
166
+ // This ensures CLI/API callers get the same validation the UI performs client-side.
167
+ const schema = plugin.manifestJson?.instanceConfigSchema;
168
+ if (schema && Object.keys(schema).length > 0) {
169
+ const validation = validateInstanceConfig(body.configJson, schema);
170
+ if (!validation.valid) {
171
+ res.status(400).json({
172
+ error: "Configuration does not match the plugin's instanceConfigSchema",
173
+ fieldErrors: validation.errors,
174
+ });
175
+ return;
176
+ }
177
+ }
178
+ try {
179
+ const result = await registry.upsertConfig(plugin.id, {
180
+ configJson: body.configJson,
181
+ });
182
+ await logPluginMutationActivity(req, "plugin.config.updated", plugin.id, {
183
+ pluginId: plugin.id,
184
+ pluginKey: plugin.pluginKey,
185
+ configKeyCount: Object.keys(body.configJson).length,
186
+ });
187
+ // Notify the running worker about the config change (PLUGIN_SPEC §25.4.4).
188
+ // If the worker implements onConfigChanged, send the new config via RPC.
189
+ // If it doesn't (METHOD_NOT_IMPLEMENTED), restart the worker so it picks
190
+ // up the new config on re-initialize. If no worker is running, skip.
191
+ if (bridgeDeps?.workerManager.isRunning(plugin.id)) {
192
+ try {
193
+ await bridgeDeps.workerManager.call(plugin.id, "configChanged", { config: body.configJson });
194
+ }
195
+ catch (rpcErr) {
196
+ if (rpcErr instanceof JsonRpcCallError &&
197
+ rpcErr.code === PLUGIN_RPC_ERROR_CODES.METHOD_NOT_IMPLEMENTED) {
198
+ // Worker doesn't handle live config — restart it.
199
+ try {
200
+ await lifecycle.restartWorker(plugin.id);
201
+ }
202
+ catch {
203
+ // Restart failure is non-fatal for the config save response.
204
+ }
205
+ }
206
+ // Other RPC errors (timeout, unavailable) are non-fatal — config is
207
+ // already persisted and will take effect on next worker restart.
208
+ }
209
+ }
210
+ res.json(result);
211
+ }
212
+ catch (err) {
213
+ const message = err instanceof Error ? err.message : String(err);
214
+ res.status(400).json({ error: message });
215
+ }
216
+ });
217
+ /**
218
+ * POST /api/plugins/:pluginId/config/test
219
+ *
220
+ * Test a plugin configuration without persisting it by calling the plugin
221
+ * worker's `validateConfig` RPC method.
222
+ *
223
+ * Only works when the plugin's worker implements `onValidateConfig`.
224
+ * If the worker does not implement the method, returns
225
+ * `{ valid: false, supported: false, message: "..." }` with HTTP 200.
226
+ *
227
+ * Request body:
228
+ * - `configJson`: Configuration values to validate
229
+ *
230
+ * Response: `{ valid: boolean; message?: string; supported?: boolean }`
231
+ * Errors:
232
+ * - 400 if request validation fails
233
+ * - 404 if plugin not found
234
+ * - 501 if bridge deps (worker manager) are not configured
235
+ * - 502 if the worker is unavailable
236
+ */
237
+ router.post("/plugins/:pluginId/config/test", async (req, res) => {
238
+ assertBoard(req);
239
+ if (!bridgeDeps) {
240
+ res.status(501).json({ error: "Plugin bridge is not enabled" });
241
+ return;
242
+ }
243
+ const { pluginId } = req.params;
244
+ const plugin = await resolvePlugin(registry, pluginId);
245
+ if (!plugin) {
246
+ res.status(404).json({ error: "Plugin not found" });
247
+ return;
248
+ }
249
+ if (plugin.status !== "ready") {
250
+ res.status(400).json({
251
+ error: `Plugin is not ready (current status: ${plugin.status})`,
252
+ });
253
+ return;
254
+ }
255
+ const body = req.body;
256
+ if (!body?.configJson || typeof body.configJson !== "object") {
257
+ res.status(400).json({ error: '"configJson" is required and must be an object' });
258
+ return;
259
+ }
260
+ // Fast schema-level rejection before hitting the worker RPC.
261
+ const schema = plugin.manifestJson?.instanceConfigSchema;
262
+ if (schema && Object.keys(schema).length > 0) {
263
+ const validation = validateInstanceConfig(body.configJson, schema);
264
+ if (!validation.valid) {
265
+ res.status(400).json({
266
+ error: "Configuration does not match the plugin's instanceConfigSchema",
267
+ fieldErrors: validation.errors,
268
+ });
269
+ return;
270
+ }
271
+ }
272
+ try {
273
+ const result = await bridgeDeps.workerManager.call(plugin.id, "validateConfig", { config: body.configJson });
274
+ // The worker returns PluginConfigValidationResult { ok, warnings?, errors? }
275
+ // Map to the frontend-expected shape { valid, message? }
276
+ if (result.ok) {
277
+ const warningText = result.warnings?.length
278
+ ? `Warnings: ${result.warnings.join("; ")}`
279
+ : undefined;
280
+ res.json({ valid: true, message: warningText });
281
+ }
282
+ else {
283
+ const errorText = result.errors?.length
284
+ ? result.errors.join("; ")
285
+ : "Configuration validation failed.";
286
+ res.json({ valid: false, message: errorText });
287
+ }
288
+ }
289
+ catch (err) {
290
+ // If the worker does not implement validateConfig, return a structured response
291
+ if (err instanceof JsonRpcCallError &&
292
+ err.code === PLUGIN_RPC_ERROR_CODES.METHOD_NOT_IMPLEMENTED) {
293
+ res.json({
294
+ valid: false,
295
+ supported: false,
296
+ message: "This plugin does not support configuration testing.",
297
+ });
298
+ return;
299
+ }
300
+ // Worker unavailable or other RPC errors
301
+ const bridgeError = mapRpcErrorToBridgeError(err);
302
+ res.status(502).json(bridgeError);
303
+ }
304
+ });
305
+ // ===========================================================================
306
+ // Job scheduling routes
307
+ // ===========================================================================
308
+ /**
309
+ * GET /api/plugins/:pluginId/jobs
310
+ *
311
+ * List all scheduled jobs for a plugin.
312
+ *
313
+ * Query params:
314
+ * - `status` (optional): Filter by job status (`active`, `paused`, `failed`)
315
+ *
316
+ * Response: PluginJobRecord[]
317
+ * Errors: 404 if plugin not found
318
+ */
319
+ router.get("/plugins/:pluginId/jobs", async (req, res) => {
320
+ assertBoard(req);
321
+ if (!jobDeps) {
322
+ res.status(501).json({ error: "Job scheduling is not enabled" });
323
+ return;
324
+ }
325
+ const { pluginId } = req.params;
326
+ const plugin = await resolvePlugin(registry, pluginId);
327
+ if (!plugin) {
328
+ res.status(404).json({ error: "Plugin not found" });
329
+ return;
330
+ }
331
+ const rawStatus = req.query.status;
332
+ const validStatuses = ["active", "paused", "failed"];
333
+ if (rawStatus !== undefined && !validStatuses.includes(rawStatus)) {
334
+ res.status(400).json({
335
+ error: `Invalid status '${rawStatus}'. Must be one of: ${validStatuses.join(", ")}`,
336
+ });
337
+ return;
338
+ }
339
+ try {
340
+ const jobs = await jobDeps.jobStore.listJobs(plugin.id, rawStatus);
341
+ res.json(jobs);
342
+ }
343
+ catch (err) {
344
+ const message = err instanceof Error ? err.message : String(err);
345
+ res.status(500).json({ error: message });
346
+ }
347
+ });
348
+ /**
349
+ * GET /api/plugins/:pluginId/jobs/:jobId/runs
350
+ *
351
+ * List execution history for a specific job.
352
+ *
353
+ * Query params:
354
+ * - `limit` (optional): Maximum number of runs to return (default: 50)
355
+ *
356
+ * Response: PluginJobRunRecord[]
357
+ * Errors: 404 if plugin not found
358
+ */
359
+ router.get("/plugins/:pluginId/jobs/:jobId/runs", async (req, res) => {
360
+ assertBoard(req);
361
+ if (!jobDeps) {
362
+ res.status(501).json({ error: "Job scheduling is not enabled" });
363
+ return;
364
+ }
365
+ const { pluginId, jobId } = req.params;
366
+ const plugin = await resolvePlugin(registry, pluginId);
367
+ if (!plugin) {
368
+ res.status(404).json({ error: "Plugin not found" });
369
+ return;
370
+ }
371
+ const job = await jobDeps.jobStore.getJobByIdForPlugin(plugin.id, jobId);
372
+ if (!job) {
373
+ res.status(404).json({ error: "Job not found" });
374
+ return;
375
+ }
376
+ const limit = req.query.limit ? parseInt(req.query.limit, 10) : 25;
377
+ if (isNaN(limit) || limit < 1 || limit > 500) {
378
+ res.status(400).json({ error: "limit must be a number between 1 and 500" });
379
+ return;
380
+ }
381
+ try {
382
+ const runs = await jobDeps.jobStore.listRunsByJob(jobId, limit);
383
+ res.json(runs);
384
+ }
385
+ catch (err) {
386
+ const message = err instanceof Error ? err.message : String(err);
387
+ res.status(500).json({ error: message });
388
+ }
389
+ });
390
+ /**
391
+ * POST /api/plugins/:pluginId/jobs/:jobId/trigger
392
+ *
393
+ * Manually trigger a job execution outside its cron schedule.
394
+ *
395
+ * Creates a run with `trigger: "manual"` and dispatches immediately.
396
+ * The response returns before the job completes (non-blocking).
397
+ *
398
+ * Response: `{ runId: string, jobId: string }`
399
+ * Errors:
400
+ * - 404 if plugin not found
401
+ * - 400 if job not found, not active, already running, or worker unavailable
402
+ */
403
+ router.post("/plugins/:pluginId/jobs/:jobId/trigger", async (req, res) => {
404
+ assertBoard(req);
405
+ if (!jobDeps) {
406
+ res.status(501).json({ error: "Job scheduling is not enabled" });
407
+ return;
408
+ }
409
+ const { pluginId, jobId } = req.params;
410
+ const plugin = await resolvePlugin(registry, pluginId);
411
+ if (!plugin) {
412
+ res.status(404).json({ error: "Plugin not found" });
413
+ return;
414
+ }
415
+ const job = await jobDeps.jobStore.getJobByIdForPlugin(plugin.id, jobId);
416
+ if (!job) {
417
+ res.status(404).json({ error: "Job not found" });
418
+ return;
419
+ }
420
+ try {
421
+ const result = await jobDeps.scheduler.triggerJob(jobId, "manual");
422
+ res.json(result);
423
+ }
424
+ catch (err) {
425
+ const message = err instanceof Error ? err.message : String(err);
426
+ res.status(400).json({ error: message });
427
+ }
428
+ });
429
+ // ===========================================================================
430
+ // Webhook ingestion route
431
+ // ===========================================================================
432
+ /**
433
+ * POST /api/plugins/:pluginId/webhooks/:endpointKey
434
+ *
435
+ * Receive an inbound webhook delivery for a plugin.
436
+ *
437
+ * This route is called by external systems (e.g. GitHub, Linear, Stripe) to
438
+ * deliver webhook payloads to a plugin. The host validates that:
439
+ * 1. The plugin exists and is in 'ready' state
440
+ * 2. The plugin declares the `webhooks.receive` capability
441
+ * 3. The `endpointKey` matches a declared webhook in the manifest
442
+ *
443
+ * The delivery is recorded in the `plugin_webhook_deliveries` table and
444
+ * dispatched to the worker via the `handleWebhook` RPC method.
445
+ *
446
+ * **Note:** This route does NOT require board authentication — webhook
447
+ * endpoints must be publicly accessible for external callers. Signature
448
+ * verification is the plugin's responsibility.
449
+ *
450
+ * Response: `{ deliveryId: string, status: string }`
451
+ * Errors:
452
+ * - 404 if plugin not found or endpointKey not declared
453
+ * - 400 if plugin is not in ready state or lacks webhooks.receive capability
454
+ * - 502 if the worker is unavailable or the RPC call fails
455
+ */
456
+ router.post("/plugins/:pluginId/webhooks/:endpointKey", async (req, res) => {
457
+ if (!webhookDeps) {
458
+ res.status(501).json({ error: "Webhook ingestion is not enabled" });
459
+ return;
460
+ }
461
+ const { pluginId, endpointKey } = req.params;
462
+ // Step 1: Resolve the plugin
463
+ const plugin = await resolvePlugin(registry, pluginId);
464
+ if (!plugin) {
465
+ res.status(404).json({ error: "Plugin not found" });
466
+ return;
467
+ }
468
+ // Step 2: Validate the plugin is in 'ready' state
469
+ if (plugin.status !== "ready") {
470
+ res.status(400).json({
471
+ error: `Plugin is not ready (current status: ${plugin.status})`,
472
+ });
473
+ return;
474
+ }
475
+ // Step 3: Validate the plugin has webhooks.receive capability
476
+ const manifest = plugin.manifestJson;
477
+ if (!manifest) {
478
+ res.status(400).json({ error: "Plugin manifest is missing" });
479
+ return;
480
+ }
481
+ const capabilities = manifest.capabilities ?? [];
482
+ if (!capabilities.includes("webhooks.receive")) {
483
+ res.status(400).json({
484
+ error: "Plugin does not have the webhooks.receive capability",
485
+ });
486
+ return;
487
+ }
488
+ // Step 4: Validate the endpointKey exists in the manifest's webhook declarations
489
+ const declaredWebhooks = manifest.webhooks ?? [];
490
+ const webhookDecl = declaredWebhooks.find((w) => w.endpointKey === endpointKey);
491
+ if (!webhookDecl) {
492
+ res.status(404).json({
493
+ error: `Webhook endpoint '${endpointKey}' is not declared by this plugin`,
494
+ });
495
+ return;
496
+ }
497
+ // Step 5: Extract request data
498
+ const requestId = randomUUID();
499
+ const rawHeaders = {};
500
+ for (const [key, value] of Object.entries(req.headers)) {
501
+ if (typeof value === "string") {
502
+ rawHeaders[key] = value;
503
+ }
504
+ else if (Array.isArray(value)) {
505
+ rawHeaders[key] = value.join(", ");
506
+ }
507
+ }
508
+ // Use the raw buffer stashed by the express.json() `verify` callback.
509
+ // This preserves the exact bytes the provider signed, whereas
510
+ // JSON.stringify(req.body) would re-serialize and break HMAC verification.
511
+ const stashedRaw = req.rawBody;
512
+ const rawBody = stashedRaw ? stashedRaw.toString("utf-8") : "";
513
+ const parsedBody = req.body;
514
+ const payload = req.body ?? {};
515
+ // Step 6: Record the delivery in the database
516
+ const startedAt = new Date();
517
+ const [delivery] = await db
518
+ .insert(pluginWebhookDeliveries)
519
+ .values({
520
+ pluginId: plugin.id,
521
+ webhookKey: endpointKey,
522
+ status: "pending",
523
+ payload,
524
+ headers: rawHeaders,
525
+ startedAt,
526
+ })
527
+ .returning({ id: pluginWebhookDeliveries.id });
528
+ // Step 7: Dispatch to the worker via handleWebhook RPC
529
+ try {
530
+ await webhookDeps.workerManager.call(plugin.id, "handleWebhook", {
531
+ endpointKey,
532
+ headers: req.headers,
533
+ rawBody,
534
+ parsedBody,
535
+ requestId,
536
+ });
537
+ // Step 8: Update delivery record to success
538
+ const finishedAt = new Date();
539
+ const durationMs = finishedAt.getTime() - startedAt.getTime();
540
+ await db
541
+ .update(pluginWebhookDeliveries)
542
+ .set({
543
+ status: "success",
544
+ durationMs,
545
+ finishedAt,
546
+ })
547
+ .where(eq(pluginWebhookDeliveries.id, delivery.id));
548
+ res.status(200).json({
549
+ deliveryId: delivery.id,
550
+ status: "success",
551
+ });
552
+ }
553
+ catch (err) {
554
+ // Step 8 (error): Update delivery record to failed
555
+ const finishedAt = new Date();
556
+ const durationMs = finishedAt.getTime() - startedAt.getTime();
557
+ const errorMessage = err instanceof Error ? err.message : String(err);
558
+ await db
559
+ .update(pluginWebhookDeliveries)
560
+ .set({
561
+ status: "failed",
562
+ durationMs,
563
+ error: errorMessage,
564
+ finishedAt,
565
+ })
566
+ .where(eq(pluginWebhookDeliveries.id, delivery.id));
567
+ res.status(502).json({
568
+ deliveryId: delivery.id,
569
+ status: "failed",
570
+ error: errorMessage,
571
+ });
572
+ }
573
+ });
574
+ // ===========================================================================
575
+ // Plugin health dashboard — aggregated diagnostics for the settings page
576
+ // ===========================================================================
577
+ /**
578
+ * GET /api/plugins/:pluginId/dashboard
579
+ *
580
+ * Aggregated health dashboard data for a plugin's settings page.
581
+ *
582
+ * Returns worker diagnostics (status, uptime, crash history), recent job
583
+ * runs, recent webhook deliveries, and the current health check result —
584
+ * all in a single response to avoid multiple round-trips.
585
+ *
586
+ * Response: PluginDashboardData
587
+ * Errors: 404 if plugin not found
588
+ */
589
+ router.get("/plugins/:pluginId/dashboard", async (req, res) => {
590
+ assertBoard(req);
591
+ const { pluginId } = req.params;
592
+ const plugin = await resolvePlugin(registry, pluginId);
593
+ if (!plugin) {
594
+ res.status(404).json({ error: "Plugin not found" });
595
+ return;
596
+ }
597
+ // --- Worker diagnostics ---
598
+ let worker = null;
599
+ // Try bridgeDeps first (primary source for worker manager), fallback to webhookDeps
600
+ const wm = bridgeDeps?.workerManager ?? webhookDeps?.workerManager ?? null;
601
+ if (wm) {
602
+ const handle = wm.getWorker(plugin.id);
603
+ if (handle) {
604
+ const diag = handle.diagnostics();
605
+ worker = {
606
+ status: diag.status,
607
+ pid: diag.pid,
608
+ uptime: diag.uptime,
609
+ consecutiveCrashes: diag.consecutiveCrashes,
610
+ totalCrashes: diag.totalCrashes,
611
+ pendingRequests: diag.pendingRequests,
612
+ lastCrashAt: diag.lastCrashAt,
613
+ nextRestartAt: diag.nextRestartAt,
614
+ };
615
+ }
616
+ }
617
+ // --- Recent job runs (last 10, newest first) ---
618
+ let recentJobRuns = [];
619
+ if (jobDeps) {
620
+ try {
621
+ const runs = await jobDeps.jobStore.listRunsByPlugin(plugin.id, undefined, 10);
622
+ // Also fetch job definitions so we can include jobKey
623
+ const jobs = await jobDeps.jobStore.listJobs(plugin.id);
624
+ const jobKeyMap = new Map(jobs.map((j) => [j.id, j.jobKey]));
625
+ recentJobRuns = runs
626
+ .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
627
+ .map((r) => ({
628
+ id: r.id,
629
+ jobId: r.jobId,
630
+ jobKey: jobKeyMap.get(r.jobId) ?? undefined,
631
+ trigger: r.trigger,
632
+ status: r.status,
633
+ durationMs: r.durationMs,
634
+ error: r.error,
635
+ startedAt: r.startedAt ? new Date(r.startedAt).toISOString() : null,
636
+ finishedAt: r.finishedAt ? new Date(r.finishedAt).toISOString() : null,
637
+ createdAt: new Date(r.createdAt).toISOString(),
638
+ }));
639
+ }
640
+ catch {
641
+ // Job data unavailable — leave empty
642
+ }
643
+ }
644
+ // --- Recent webhook deliveries (last 10, newest first) ---
645
+ let recentWebhookDeliveries = [];
646
+ try {
647
+ const deliveries = await db
648
+ .select({
649
+ id: pluginWebhookDeliveries.id,
650
+ webhookKey: pluginWebhookDeliveries.webhookKey,
651
+ status: pluginWebhookDeliveries.status,
652
+ durationMs: pluginWebhookDeliveries.durationMs,
653
+ error: pluginWebhookDeliveries.error,
654
+ startedAt: pluginWebhookDeliveries.startedAt,
655
+ finishedAt: pluginWebhookDeliveries.finishedAt,
656
+ createdAt: pluginWebhookDeliveries.createdAt,
657
+ })
658
+ .from(pluginWebhookDeliveries)
659
+ .where(eq(pluginWebhookDeliveries.pluginId, plugin.id))
660
+ .orderBy(desc(pluginWebhookDeliveries.createdAt))
661
+ .limit(10);
662
+ recentWebhookDeliveries = deliveries.map((d) => ({
663
+ id: d.id,
664
+ webhookKey: d.webhookKey,
665
+ status: d.status,
666
+ durationMs: d.durationMs,
667
+ error: d.error,
668
+ startedAt: d.startedAt ? d.startedAt.toISOString() : null,
669
+ finishedAt: d.finishedAt ? d.finishedAt.toISOString() : null,
670
+ createdAt: d.createdAt.toISOString(),
671
+ }));
672
+ }
673
+ catch {
674
+ // Webhook data unavailable — leave empty
675
+ }
676
+ // --- Health check (same logic as GET /health) ---
677
+ const checks = [];
678
+ checks.push({
679
+ name: "registry",
680
+ passed: true,
681
+ message: "Plugin found in registry",
682
+ });
683
+ const hasValidManifest = Boolean(plugin.manifestJson?.id);
684
+ checks.push({
685
+ name: "manifest",
686
+ passed: hasValidManifest,
687
+ message: hasValidManifest ? "Manifest is valid" : "Manifest is invalid or missing",
688
+ });
689
+ const isHealthy = plugin.status === "ready";
690
+ checks.push({
691
+ name: "status",
692
+ passed: isHealthy,
693
+ message: `Current status: ${plugin.status}`,
694
+ });
695
+ const hasNoError = !plugin.lastError;
696
+ if (!hasNoError) {
697
+ checks.push({
698
+ name: "error_state",
699
+ passed: false,
700
+ message: plugin.lastError ?? undefined,
701
+ });
702
+ }
703
+ const health = {
704
+ pluginId: plugin.id,
705
+ status: plugin.status,
706
+ healthy: isHealthy && hasValidManifest && hasNoError,
707
+ checks,
708
+ lastError: plugin.lastError ?? undefined,
709
+ };
710
+ res.json({
711
+ pluginId: plugin.id,
712
+ worker,
713
+ recentJobRuns,
714
+ recentWebhookDeliveries,
715
+ health,
716
+ checkedAt: new Date().toISOString(),
717
+ });
718
+ });
719
+ }
720
+ //# sourceMappingURL=plugins.operations-routes.js.map