@rudderhq/server 0.2.5-canary.9 → 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-B5mJzzqZ.js → _basePickBy-N8I9ml5Y.js} +1 -1
  232. package/ui-dist/assets/{_baseUniq-B10Ec09o.js → _baseUniq-BuSlpRSQ.js} +1 -1
  233. package/ui-dist/assets/{arc-Bw7wimOa.js → arc-qX-dPyA1.js} +1 -1
  234. package/ui-dist/assets/{architectureDiagram-2XIMDMQ5-DZr0XEvv.js → architectureDiagram-2XIMDMQ5-DhjkbXsp.js} +1 -1
  235. package/ui-dist/assets/{blockDiagram-WCTKOSBZ-D0jl0LgB.js → blockDiagram-WCTKOSBZ-JS-tTu3J.js} +1 -1
  236. package/ui-dist/assets/{c4Diagram-IC4MRINW-BEFxBnEm.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-Cbul1GoA.js → chunk-4BX2VUAB-T37SqBpp.js} +1 -1
  239. package/ui-dist/assets/{chunk-55IACEB6-DuouC3bT.js → chunk-55IACEB6-BSj9hdqK.js} +1 -1
  240. package/ui-dist/assets/{chunk-FMBD7UC4-bN1jF9xw.js → chunk-FMBD7UC4-Dkrlh0Wk.js} +1 -1
  241. package/ui-dist/assets/{chunk-JSJVCQXG-B0-Ij6ZF.js → chunk-JSJVCQXG-C0ZE3QdB.js} +1 -1
  242. package/ui-dist/assets/{chunk-KX2RTZJC-BjI3IEjI.js → chunk-KX2RTZJC-DOZQM9gW.js} +1 -1
  243. package/ui-dist/assets/{chunk-NQ4KR5QH-MUoGr46n.js → chunk-NQ4KR5QH-5Yr3U2k8.js} +1 -1
  244. package/ui-dist/assets/{chunk-QZHKN3VN-CQoI9Ouy.js → chunk-QZHKN3VN-CvKTufwF.js} +1 -1
  245. package/ui-dist/assets/{chunk-WL4C6EOR-DSJh3iDp.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-BPepglgB.js → cose-bilkent-S5V4N54A-CTvr1OFj.js} +1 -1
  250. package/ui-dist/assets/{dagre-KLK3FWXG-DhnHVZkt.js → dagre-KLK3FWXG-UZ-SNjVK.js} +1 -1
  251. package/ui-dist/assets/{diagram-E7M64L7V-DNvXtoOO.js → diagram-E7M64L7V-D7RAN0Hr.js} +1 -1
  252. package/ui-dist/assets/{diagram-IFDJBPK2-DhGlDTgn.js → diagram-IFDJBPK2-B4LViaFR.js} +1 -1
  253. package/ui-dist/assets/{diagram-P4PSJMXO-BmXEloWS.js → diagram-P4PSJMXO-CY1be7ak.js} +1 -1
  254. package/ui-dist/assets/{erDiagram-INFDFZHY-BTYVzaLM.js → erDiagram-INFDFZHY-Dca0KkvJ.js} +1 -1
  255. package/ui-dist/assets/{flowDiagram-PKNHOUZH-CqMNQUVv.js → flowDiagram-PKNHOUZH-i-qMvfwg.js} +1 -1
  256. package/ui-dist/assets/{ganttDiagram-A5KZAMGK-B2le_64a.js → ganttDiagram-A5KZAMGK-Wxq2lhbh.js} +1 -1
  257. package/ui-dist/assets/{gitGraphDiagram-K3NZZRJ6-BtxOBq5A.js → gitGraphDiagram-K3NZZRJ6-DwzgPlAY.js} +1 -1
  258. package/ui-dist/assets/{graph-C5E6qFfm.js → graph-BAqf89Tz.js} +1 -1
  259. package/ui-dist/assets/{index-Piq-IPXt.js → index-4eCzaLuY.js} +1 -1
  260. package/ui-dist/assets/{index-DT6UN2ec.js → index-8uu-nKqK.js} +1 -1
  261. package/ui-dist/assets/{index-T5NVZ3nR.js → index-B-1NEcI_.js} +1 -1
  262. package/ui-dist/assets/{index-D-MoarxG.js → index-B0b_3Eu5.js} +1 -1
  263. package/ui-dist/assets/{index-CZiP3FBQ.js → index-B8v0eZjP.js} +1 -1
  264. package/ui-dist/assets/{index-C1Ga66FM.js → index-BN7Moj3u.js} +1 -1
  265. package/ui-dist/assets/{index-xBUfBdQn.js → index-BSpxh3cY.js} +1 -1
  266. package/ui-dist/assets/{index-CQcMWp51.js → index-BY44RIi9.js} +1 -1
  267. package/ui-dist/assets/{index-3a93sZNI.js → index-BhyQJhdZ.js} +1 -1
  268. package/ui-dist/assets/{index-BsVDit5y.js → index-BkPL_iGU.js} +1 -1
  269. package/ui-dist/assets/{index-88lBSTsW.js → index-BsPfoHXS.js} +1 -1
  270. package/ui-dist/assets/{index-CyJtcUF0.js → index-BstW7nmv.js} +1 -1
  271. package/ui-dist/assets/{index-BvZ0Ptfl.js → index-BwB67Zyz.js} +1 -1
  272. package/ui-dist/assets/index-C2peSkmT.css +1 -0
  273. package/ui-dist/assets/{index-vkCrQLeX.js → index-C3ktOsS_.js} +1 -1
  274. package/ui-dist/assets/{index-D2hZpQJT.js → index-CMyABlS-.js} +1 -1
  275. package/ui-dist/assets/{index-C4WCPEY4.js → index-CyBJ8ujC.js} +1 -1
  276. package/ui-dist/assets/{index-Bf7NB_lK.js → index-DAxM2W3O.js} +1 -1
  277. package/ui-dist/assets/{index-Dq7H6-Lm.js → index-DVZXPmhk.js} +1 -1
  278. package/ui-dist/assets/{index-CskDu6A3.js → index-Dc19uAyw.js} +1 -1
  279. package/ui-dist/assets/index-DzHrwZu1.js +1511 -0
  280. package/ui-dist/assets/{index-B20JneLK.js → index-LJuf53Ye.js} +1 -1
  281. package/ui-dist/assets/{index-D6McTDMQ.js → index-Ugw5VWWz.js} +1 -1
  282. package/ui-dist/assets/{index-CcVGS6HJ.js → index-YGraEFR7.js} +1 -1
  283. package/ui-dist/assets/{infoDiagram-LFFYTUFH-BiCCZcIW.js → infoDiagram-LFFYTUFH-jLmDtFVR.js} +1 -1
  284. package/ui-dist/assets/{ishikawaDiagram-PHBUUO56-BiwBemM5.js → ishikawaDiagram-PHBUUO56-6OGMyLT8.js} +1 -1
  285. package/ui-dist/assets/{journeyDiagram-4ABVD52K-D8RGr2xl.js → journeyDiagram-4ABVD52K-yQjl6E0t.js} +1 -1
  286. package/ui-dist/assets/{kanban-definition-K7BYSVSG-C733Fj-E.js → kanban-definition-K7BYSVSG-DkdCeQlS.js} +1 -1
  287. package/ui-dist/assets/{layout-CM4c3NA_.js → layout-CqSYvZ_w.js} +1 -1
  288. package/ui-dist/assets/{linear-DzH21Xsf.js → linear-B8xGZaoi.js} +1 -1
  289. package/ui-dist/assets/{mermaid.core-Z2rpoVP2.js → mermaid.core-AKL_cdyk.js} +4 -4
  290. package/ui-dist/assets/{mindmap-definition-YRQLILUH-DylLLj9w.js → mindmap-definition-YRQLILUH-Zr-dXC0x.js} +1 -1
  291. package/ui-dist/assets/{pieDiagram-SKSYHLDU-617wI_rr.js → pieDiagram-SKSYHLDU-BvDAU-Nk.js} +1 -1
  292. package/ui-dist/assets/{quadrantDiagram-337W2JSQ-lxoCPJIL.js → quadrantDiagram-337W2JSQ-Dn9kM62o.js} +1 -1
  293. package/ui-dist/assets/{requirementDiagram-Z7DCOOCP-C5XydQ9-.js → requirementDiagram-Z7DCOOCP-GIsIh7Sd.js} +1 -1
  294. package/ui-dist/assets/{sankeyDiagram-WA2Y5GQK--grmq-Q8.js → sankeyDiagram-WA2Y5GQK-CUCuBkuf.js} +1 -1
  295. package/ui-dist/assets/{sequenceDiagram-2WXFIKYE-BS2PeYH-.js → sequenceDiagram-2WXFIKYE-MDpUY2HM.js} +1 -1
  296. package/ui-dist/assets/{stateDiagram-RAJIS63D-CeuZtj2z.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-DxHdMpRr.js → timeline-definition-YZTLITO2-B6ofPhhy.js} +1 -1
  299. package/ui-dist/assets/{treemap-KZPCXAKY-Bv1ZlC5h.js → treemap-KZPCXAKY-DnLO6w1l.js} +1 -1
  300. package/ui-dist/assets/{vennDiagram-LZ73GAT5-DvpZSXY2.js → vennDiagram-LZ73GAT5-D0MyZIDl.js} +1 -1
  301. package/ui-dist/assets/{xychartDiagram-JWTSCODW-DttOu1GC.js → xychartDiagram-JWTSCODW-rADY1iUG.js} +1 -1
  302. package/ui-dist/index.html +2 -2
  303. package/ui-dist/assets/channel-DGUh6rEi.js +0 -1
  304. package/ui-dist/assets/classDiagram-VBA2DB6C-1ntk2IOV.js +0 -1
  305. package/ui-dist/assets/classDiagram-v2-RAHNMMFH-1ntk2IOV.js +0 -1
  306. package/ui-dist/assets/clone-BpddY88c.js +0 -1
  307. package/ui-dist/assets/index-C8AD6s7S.js +0 -1510
  308. package/ui-dist/assets/index-Ded0dPwB.css +0 -1
  309. package/ui-dist/assets/stateDiagram-v2-FVOUBMTO-DXq0yC5C.js +0 -1
@@ -0,0 +1,997 @@
1
+ import { createHash } from "node:crypto";
2
+ import { execFile } from "node:child_process";
3
+ import path from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { AUTOMATION_CATCH_UP_POLICIES, AUTOMATION_CONCURRENCY_POLICIES, AUTOMATION_TRIGGER_KINDS, AUTOMATION_TRIGGER_SIGNING_MODES, deriveProjectUrlKey, getBundledRudderSkillSlug, normalizeAgentUrlKey, toBundledRudderSkillKey, } from "@rudderhq/shared";
6
+ import { validateCron } from "../cron.js";
7
+ /** Build OrgNode tree from manifest agent list (slug + reportsToSlug). */
8
+ export function buildOrgTreeFromManifest(agents) {
9
+ const ROLE_LABELS = {
10
+ ceo: "Chief Executive", cto: "Technology", cmo: "Marketing",
11
+ cfo: "Finance", coo: "Operations", vp: "VP", manager: "Manager",
12
+ engineer: "Engineer", agent: "Agent",
13
+ };
14
+ const bySlug = new Map(agents.map((a) => [a.slug, a]));
15
+ const childrenOf = new Map();
16
+ for (const a of agents) {
17
+ const parent = a.reportsToSlug ?? null;
18
+ const list = childrenOf.get(parent) ?? [];
19
+ list.push(a);
20
+ childrenOf.set(parent, list);
21
+ }
22
+ const build = (parentSlug) => {
23
+ const members = childrenOf.get(parentSlug) ?? [];
24
+ return members.map((m) => ({
25
+ id: m.slug,
26
+ name: m.name,
27
+ role: ROLE_LABELS[m.role] ?? m.role,
28
+ status: "active",
29
+ reports: build(m.slug),
30
+ }));
31
+ };
32
+ // Find roots: agents whose reportsToSlug is null or points to a non-existent slug
33
+ const roots = agents.filter((a) => !a.reportsToSlug || !bySlug.has(a.reportsToSlug));
34
+ const rootSlugs = new Set(roots.map((r) => r.slug));
35
+ // Start from null parent, but also include orphans
36
+ const tree = build(null);
37
+ for (const root of roots) {
38
+ if (root.reportsToSlug && !bySlug.has(root.reportsToSlug)) {
39
+ // Orphan root (parent slug doesn't exist)
40
+ tree.push({
41
+ id: root.slug,
42
+ name: root.name,
43
+ role: ROLE_LABELS[root.role] ?? root.role,
44
+ status: "active",
45
+ reports: build(root.slug),
46
+ });
47
+ }
48
+ }
49
+ return tree;
50
+ }
51
+ export const DEFAULT_INCLUDE = {
52
+ organization: true,
53
+ agents: true,
54
+ projects: false,
55
+ issues: false,
56
+ skills: false,
57
+ };
58
+ export const DEFAULT_COLLISION_STRATEGY = "rename";
59
+ export const PORTABLE_AGENT_ENTRY_FILE = "AGENTS.md";
60
+ export const execFileAsync = promisify(execFile);
61
+ export let bundledSkillsCommitPromise = null;
62
+ export function resolveImportMode(options) {
63
+ return options?.mode ?? "board_full";
64
+ }
65
+ export function resolveSkillConflictStrategy(mode, collisionStrategy) {
66
+ if (mode === "board_full")
67
+ return "replace";
68
+ return collisionStrategy === "skip" ? "skip" : "rename";
69
+ }
70
+ export function normalizePortablePath(input) {
71
+ const normalized = input.replace(/\\/g, "/").replace(/^\.\/+/, "");
72
+ const parts = [];
73
+ for (const part of normalized.split("/")) {
74
+ if (!part || part === ".")
75
+ continue;
76
+ if (part === "..") {
77
+ if (parts.length > 0)
78
+ parts.pop();
79
+ continue;
80
+ }
81
+ parts.push(part);
82
+ }
83
+ return parts.join("/");
84
+ }
85
+ export function classifyPortableFileKind(pathValue) {
86
+ const normalized = normalizePortablePath(pathValue);
87
+ if (normalized === "ORGANIZATION.md")
88
+ return "organization";
89
+ if (normalized === ".rudder.yaml" || normalized === ".rudder.yml")
90
+ return "extension";
91
+ if (normalized === "README.md")
92
+ return "readme";
93
+ if (normalized.startsWith("agents/"))
94
+ return "agent";
95
+ if (normalized.startsWith("skills/") || normalized.startsWith(".agents/skills/"))
96
+ return "skill";
97
+ if (normalized.startsWith("projects/"))
98
+ return "project";
99
+ if (normalized.startsWith("tasks/"))
100
+ return "issue";
101
+ return "other";
102
+ }
103
+ export function normalizeSkillSlug(value) {
104
+ return value ? normalizeAgentUrlKey(value) ?? null : null;
105
+ }
106
+ export function normalizeSkillKey(value) {
107
+ if (!value)
108
+ return null;
109
+ const segments = value
110
+ .split("/")
111
+ .map((segment) => normalizeSkillSlug(segment))
112
+ .filter((segment) => Boolean(segment));
113
+ return segments.length > 0 ? segments.join("/") : null;
114
+ }
115
+ export function readSkillKey(frontmatter) {
116
+ const metadata = isPlainRecord(frontmatter.metadata) ? frontmatter.metadata : null;
117
+ const rudder = isPlainRecord(metadata?.rudder) ? metadata?.rudder : null;
118
+ return normalizeSkillKey(asString(frontmatter.key)
119
+ ?? asString(frontmatter.skillKey)
120
+ ?? asString(metadata?.skillKey)
121
+ ?? asString(metadata?.canonicalKey)
122
+ ?? asString(metadata?.rudderSkillKey)
123
+ ?? asString(rudder?.skillKey)
124
+ ?? asString(rudder?.key));
125
+ }
126
+ export function deriveManifestSkillKey(frontmatter, fallbackSlug, metadata, sourceType, sourceLocator) {
127
+ const slug = normalizeSkillSlug(asString(frontmatter.slug) ?? fallbackSlug) ?? "skill";
128
+ const sourceKind = asString(metadata?.sourceKind);
129
+ const explicit = readSkillKey(frontmatter);
130
+ if (explicit) {
131
+ if (isBundledRudderSourceKind(sourceKind)) {
132
+ return toBundledRudderSkillKey(getBundledRudderSkillSlug(explicit) ?? slug) ?? explicit;
133
+ }
134
+ return explicit;
135
+ }
136
+ const owner = normalizeSkillSlug(asString(metadata?.owner));
137
+ const repo = normalizeSkillSlug(asString(metadata?.repo));
138
+ if ((sourceType === "github" || sourceType === "skills_sh" || sourceKind === "github" || sourceKind === "skills_sh") && owner && repo) {
139
+ return `${owner}/${repo}/${slug}`;
140
+ }
141
+ if (isBundledRudderSourceKind(sourceKind)) {
142
+ return toBundledRudderSkillKey(slug) ?? `rudder/${slug}`;
143
+ }
144
+ if (sourceType === "url" || sourceKind === "url") {
145
+ try {
146
+ const host = normalizeSkillSlug(sourceLocator ? new URL(sourceLocator).host : null) ?? "url";
147
+ return `url/${host}/${slug}`;
148
+ }
149
+ catch {
150
+ return `url/unknown/${slug}`;
151
+ }
152
+ }
153
+ return slug;
154
+ }
155
+ export function hashSkillValue(value) {
156
+ return createHash("sha256").update(value).digest("hex").slice(0, 8);
157
+ }
158
+ export function normalizeExportPathSegment(value, preserveCase = false) {
159
+ if (!value)
160
+ return null;
161
+ const trimmed = value.trim();
162
+ if (!trimmed)
163
+ return null;
164
+ const normalized = trimmed
165
+ .replace(/[^A-Za-z0-9._-]+/g, "-")
166
+ .replace(/-+/g, "-")
167
+ .replace(/^-+|-+$/g, "");
168
+ if (!normalized)
169
+ return null;
170
+ return preserveCase ? normalized : normalized.toLowerCase();
171
+ }
172
+ export function readSkillSourceKind(skill) {
173
+ const metadata = isPlainRecord(skill.metadata) ? skill.metadata : null;
174
+ return asString(metadata?.sourceKind);
175
+ }
176
+ export function isBundledRudderSourceKind(value) {
177
+ return value === "rudder_bundled" || value === "paperclip_bundled";
178
+ }
179
+ export function deriveLocalExportNamespace(skill, slug) {
180
+ const metadata = isPlainRecord(skill.metadata) ? skill.metadata : null;
181
+ const candidates = [
182
+ asString(metadata?.projectName),
183
+ asString(metadata?.workspaceName),
184
+ ];
185
+ if (skill.sourceLocator) {
186
+ const basename = path.basename(skill.sourceLocator);
187
+ candidates.push(basename.toLowerCase() === "skill.md" ? path.basename(path.dirname(skill.sourceLocator)) : basename);
188
+ }
189
+ for (const value of candidates) {
190
+ const normalized = normalizeSkillSlug(value);
191
+ if (normalized && normalized !== slug)
192
+ return normalized;
193
+ }
194
+ return null;
195
+ }
196
+ export function derivePrimarySkillExportDir(skill, slug, organizationIssuePrefix) {
197
+ const sourceKind = readSkillSourceKind(skill);
198
+ const canonicalKey = isBundledRudderSourceKind(sourceKind)
199
+ ? toBundledRudderSkillKey(getBundledRudderSkillSlug(skill.key) ?? slug) ?? skill.key
200
+ : skill.key;
201
+ const normalizedKey = normalizeSkillKey(canonicalKey);
202
+ const keySegments = normalizedKey?.split("/") ?? [];
203
+ const primaryNamespace = keySegments[0] ?? null;
204
+ if (primaryNamespace === "organization") {
205
+ const companySegment = normalizeExportPathSegment(organizationIssuePrefix, true)
206
+ ?? normalizeExportPathSegment(keySegments[1], true)
207
+ ?? "organization";
208
+ return `skills/organization/${companySegment}/${slug}`;
209
+ }
210
+ if (primaryNamespace === "local") {
211
+ const localNamespace = deriveLocalExportNamespace(skill, slug);
212
+ return localNamespace
213
+ ? `skills/local/${localNamespace}/${slug}`
214
+ : `skills/local/${slug}`;
215
+ }
216
+ if (primaryNamespace === "url") {
217
+ let derivedHost = keySegments[1] ?? null;
218
+ if (!derivedHost) {
219
+ try {
220
+ derivedHost = normalizeSkillSlug(skill.sourceLocator ? new URL(skill.sourceLocator).host : null);
221
+ }
222
+ catch {
223
+ derivedHost = null;
224
+ }
225
+ }
226
+ const host = derivedHost ?? "url";
227
+ return `skills/url/${host}/${slug}`;
228
+ }
229
+ if (keySegments.length > 1) {
230
+ return `skills/${keySegments.join("/")}`;
231
+ }
232
+ return `skills/${slug}`;
233
+ }
234
+ export function appendSkillExportDirSuffix(packageDir, suffix) {
235
+ const lastSeparator = packageDir.lastIndexOf("/");
236
+ if (lastSeparator < 0)
237
+ return `${packageDir}--${suffix}`;
238
+ return `${packageDir.slice(0, lastSeparator + 1)}${packageDir.slice(lastSeparator + 1)}--${suffix}`;
239
+ }
240
+ export function deriveSkillExportDirCandidates(skill, slug, organizationIssuePrefix) {
241
+ const primaryDir = derivePrimarySkillExportDir(skill, slug, organizationIssuePrefix);
242
+ const metadata = isPlainRecord(skill.metadata) ? skill.metadata : null;
243
+ const sourceKind = readSkillSourceKind(skill);
244
+ const suffixes = new Set();
245
+ const pushSuffix = (value, preserveCase = false) => {
246
+ const normalized = normalizeExportPathSegment(value, preserveCase);
247
+ if (normalized && normalized !== slug) {
248
+ suffixes.add(normalized);
249
+ }
250
+ };
251
+ if (isBundledRudderSourceKind(sourceKind)) {
252
+ pushSuffix("rudder");
253
+ }
254
+ if (skill.sourceType === "github" || skill.sourceType === "skills_sh") {
255
+ pushSuffix(asString(metadata?.repo));
256
+ pushSuffix(asString(metadata?.owner));
257
+ pushSuffix(skill.sourceType === "skills_sh" ? "skills_sh" : "github");
258
+ }
259
+ else if (skill.sourceType === "url") {
260
+ try {
261
+ pushSuffix(skill.sourceLocator ? new URL(skill.sourceLocator).host : null);
262
+ }
263
+ catch {
264
+ // Ignore URL parse failures and fall through to generic suffixes.
265
+ }
266
+ pushSuffix("url");
267
+ }
268
+ else if (skill.sourceType === "local_path") {
269
+ pushSuffix(asString(metadata?.projectName));
270
+ pushSuffix(asString(metadata?.workspaceName));
271
+ pushSuffix(deriveLocalExportNamespace(skill, slug));
272
+ if (sourceKind === "managed_local")
273
+ pushSuffix("organization");
274
+ if (sourceKind === "project_scan")
275
+ pushSuffix("project");
276
+ pushSuffix("local");
277
+ }
278
+ else {
279
+ pushSuffix(sourceKind);
280
+ pushSuffix("skill");
281
+ }
282
+ return [primaryDir, ...Array.from(suffixes, (suffix) => appendSkillExportDirSuffix(primaryDir, suffix))];
283
+ }
284
+ export function buildSkillExportDirMap(skills, organizationIssuePrefix) {
285
+ const usedDirs = new Set();
286
+ const keyToDir = new Map();
287
+ const orderedSkills = [...skills].sort((left, right) => left.key.localeCompare(right.key));
288
+ for (const skill of orderedSkills) {
289
+ const slug = normalizeSkillSlug(skill.slug) ?? "skill";
290
+ const candidates = deriveSkillExportDirCandidates(skill, slug, organizationIssuePrefix);
291
+ let packageDir = candidates.find((candidate) => !usedDirs.has(candidate)) ?? null;
292
+ if (!packageDir) {
293
+ packageDir = appendSkillExportDirSuffix(candidates[0] ?? `skills/${slug}`, hashSkillValue(skill.key));
294
+ while (usedDirs.has(packageDir)) {
295
+ packageDir = appendSkillExportDirSuffix(candidates[0] ?? `skills/${slug}`, hashSkillValue(`${skill.key}:${packageDir}`));
296
+ }
297
+ }
298
+ usedDirs.add(packageDir);
299
+ keyToDir.set(skill.key, packageDir);
300
+ }
301
+ return keyToDir;
302
+ }
303
+ export function isSensitiveEnvKey(key) {
304
+ const normalized = key.trim().toLowerCase();
305
+ return (normalized === "token" ||
306
+ normalized.endsWith("_token") ||
307
+ normalized.endsWith("-token") ||
308
+ normalized.includes("apikey") ||
309
+ normalized.includes("api_key") ||
310
+ normalized.includes("api-key") ||
311
+ normalized.includes("access_token") ||
312
+ normalized.includes("access-token") ||
313
+ normalized.includes("auth") ||
314
+ normalized.includes("auth_token") ||
315
+ normalized.includes("auth-token") ||
316
+ normalized.includes("authorization") ||
317
+ normalized.includes("bearer") ||
318
+ normalized.includes("secret") ||
319
+ normalized.includes("passwd") ||
320
+ normalized.includes("password") ||
321
+ normalized.includes("credential") ||
322
+ normalized.includes("jwt") ||
323
+ normalized.includes("privatekey") ||
324
+ normalized.includes("private_key") ||
325
+ normalized.includes("private-key") ||
326
+ normalized.includes("cookie") ||
327
+ normalized.includes("connectionstring"));
328
+ }
329
+ export const COMPANY_LOGO_CONTENT_TYPE_EXTENSIONS = {
330
+ "image/gif": ".gif",
331
+ "image/jpeg": ".jpg",
332
+ "image/png": ".png",
333
+ "image/svg+xml": ".svg",
334
+ "image/webp": ".webp",
335
+ };
336
+ export const COMPANY_LOGO_FILE_NAME = "organization-logo";
337
+ export const RUNTIME_DEFAULT_RULES = [
338
+ { path: ["heartbeat", "cooldownSec"], value: 10 },
339
+ { path: ["heartbeat", "intervalSec"], value: 3600 },
340
+ { path: ["heartbeat", "wakeOnOnDemand"], value: true },
341
+ { path: ["heartbeat", "wakeOnAssignment"], value: true },
342
+ { path: ["heartbeat", "wakeOnAutomation"], value: true },
343
+ { path: ["heartbeat", "wakeOnDemand"], value: true },
344
+ { path: ["heartbeat", "preflightEnabled"], value: true },
345
+ { path: ["heartbeat", "maxConcurrentRuns"], value: 3 },
346
+ ];
347
+ export const ADAPTER_DEFAULT_RULES_BY_TYPE = {
348
+ codex_local: [
349
+ { path: ["timeoutSec"], value: 0 },
350
+ { path: ["graceSec"], value: 15 },
351
+ ],
352
+ gemini_local: [
353
+ { path: ["timeoutSec"], value: 0 },
354
+ { path: ["graceSec"], value: 15 },
355
+ ],
356
+ opencode_local: [
357
+ { path: ["timeoutSec"], value: 0 },
358
+ { path: ["graceSec"], value: 15 },
359
+ ],
360
+ cursor: [
361
+ { path: ["timeoutSec"], value: 0 },
362
+ { path: ["graceSec"], value: 15 },
363
+ ],
364
+ claude_local: [
365
+ { path: ["timeoutSec"], value: 0 },
366
+ { path: ["graceSec"], value: 15 },
367
+ { path: ["maxTurnsPerRun"], value: 300 },
368
+ ],
369
+ openclaw_gateway: [
370
+ { path: ["timeoutSec"], value: 120 },
371
+ { path: ["waitTimeoutMs"], value: 120000 },
372
+ { path: ["sessionKeyStrategy"], value: "fixed" },
373
+ { path: ["sessionKey"], value: "rudder" },
374
+ { path: ["role"], value: "operator" },
375
+ { path: ["scopes"], value: ["operator.admin"] },
376
+ ],
377
+ };
378
+ export function isPlainRecord(value) {
379
+ return typeof value === "object" && value !== null && !Array.isArray(value);
380
+ }
381
+ export function asString(value) {
382
+ if (typeof value !== "string")
383
+ return null;
384
+ const trimmed = value.trim();
385
+ return trimmed.length > 0 ? trimmed : null;
386
+ }
387
+ export function asBoolean(value) {
388
+ return typeof value === "boolean" ? value : null;
389
+ }
390
+ export function asInteger(value) {
391
+ return typeof value === "number" && Number.isInteger(value) ? value : null;
392
+ }
393
+ export function normalizeAutomationTriggerExtension(value) {
394
+ if (!isPlainRecord(value))
395
+ return null;
396
+ const kind = asString(value.kind);
397
+ if (!kind)
398
+ return null;
399
+ return {
400
+ kind,
401
+ label: asString(value.label),
402
+ enabled: asBoolean(value.enabled) ?? true,
403
+ cronExpression: asString(value.cronExpression),
404
+ timezone: asString(value.timezone),
405
+ signingMode: asString(value.signingMode),
406
+ replayWindowSec: asInteger(value.replayWindowSec),
407
+ };
408
+ }
409
+ export function normalizeAutomationExtension(value) {
410
+ if (!isPlainRecord(value))
411
+ return null;
412
+ const triggers = Array.isArray(value.triggers)
413
+ ? value.triggers
414
+ .map((entry) => normalizeAutomationTriggerExtension(entry))
415
+ .filter((entry) => entry !== null)
416
+ : [];
417
+ const automation = {
418
+ concurrencyPolicy: asString(value.concurrencyPolicy),
419
+ catchUpPolicy: asString(value.catchUpPolicy),
420
+ triggers,
421
+ };
422
+ return stripEmptyValues(automation) ? automation : null;
423
+ }
424
+ export function buildAutomationManifestFromLiveAutomation(automation) {
425
+ return {
426
+ concurrencyPolicy: automation.concurrencyPolicy,
427
+ catchUpPolicy: automation.catchUpPolicy,
428
+ triggers: automation.triggers.map((trigger) => ({
429
+ kind: trigger.kind,
430
+ label: trigger.label ?? null,
431
+ enabled: Boolean(trigger.enabled),
432
+ cronExpression: trigger.kind === "schedule" ? trigger.cronExpression ?? null : null,
433
+ timezone: trigger.kind === "schedule" ? trigger.timezone ?? null : null,
434
+ signingMode: trigger.kind === "webhook" ? trigger.signingMode ?? null : null,
435
+ replayWindowSec: trigger.kind === "webhook" ? trigger.replayWindowSec ?? null : null,
436
+ })),
437
+ };
438
+ }
439
+ export function containsAbsolutePathFragment(value) {
440
+ return /(^|\s)(\/[^/\s]|[A-Za-z]:[\\/])/.test(value);
441
+ }
442
+ export function containsSystemDependentPathValue(value) {
443
+ if (typeof value === "string") {
444
+ return path.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || containsAbsolutePathFragment(value);
445
+ }
446
+ if (Array.isArray(value)) {
447
+ return value.some((entry) => containsSystemDependentPathValue(entry));
448
+ }
449
+ if (isPlainRecord(value)) {
450
+ return Object.values(value).some((entry) => containsSystemDependentPathValue(entry));
451
+ }
452
+ return false;
453
+ }
454
+ export function clonePortableRecord(value) {
455
+ if (!isPlainRecord(value))
456
+ return null;
457
+ return structuredClone(value);
458
+ }
459
+ export function isEmptyObject(value) {
460
+ return isPlainRecord(value) && Object.keys(value).length === 0;
461
+ }
462
+ export function isEmptyArray(value) {
463
+ return Array.isArray(value) && value.length === 0;
464
+ }
465
+ export function stripEmptyValues(value, opts) {
466
+ if (Array.isArray(value)) {
467
+ const next = value
468
+ .map((entry) => stripEmptyValues(entry, opts))
469
+ .filter((entry) => entry !== undefined && !isEmptyObject(entry) && !isEmptyArray(entry));
470
+ return next.length > 0 ? next : undefined;
471
+ }
472
+ if (isPlainRecord(value)) {
473
+ const out = {};
474
+ for (const [key, entry] of Object.entries(value)) {
475
+ const stripped = stripEmptyValues(entry, opts);
476
+ if (stripped === undefined || stripped === null)
477
+ continue;
478
+ if (!opts?.preserveEmptyStrings && stripped === "")
479
+ continue;
480
+ if (isEmptyObject(stripped) || isEmptyArray(stripped))
481
+ continue;
482
+ out[key] = stripped;
483
+ }
484
+ return Object.keys(out).length > 0 ? out : undefined;
485
+ }
486
+ return value;
487
+ }
488
+ export function disableImportedTimerHeartbeat(runtimeConfig) {
489
+ const next = clonePortableRecord(runtimeConfig) ?? {};
490
+ const heartbeat = isPlainRecord(next.heartbeat) ? { ...next.heartbeat } : {};
491
+ heartbeat.enabled = false;
492
+ next.heartbeat = heartbeat;
493
+ return next;
494
+ }
495
+ export function normalizePortableProjectWorkspaceExtension(workspaceKey, value) {
496
+ if (!isPlainRecord(value))
497
+ return null;
498
+ const normalizedKey = normalizeAgentUrlKey(workspaceKey) ?? workspaceKey.trim();
499
+ if (!normalizedKey)
500
+ return null;
501
+ return {
502
+ key: normalizedKey,
503
+ name: asString(value.name) ?? normalizedKey,
504
+ sourceType: asString(value.sourceType),
505
+ repoUrl: asString(value.repoUrl),
506
+ repoRef: asString(value.repoRef),
507
+ defaultRef: asString(value.defaultRef),
508
+ visibility: asString(value.visibility),
509
+ setupCommand: asString(value.setupCommand),
510
+ cleanupCommand: asString(value.cleanupCommand),
511
+ metadata: isPlainRecord(value.metadata) ? value.metadata : null,
512
+ isPrimary: asBoolean(value.isPrimary) ?? false,
513
+ };
514
+ }
515
+ export function derivePortableProjectWorkspaceKey(workspace, usedKeys) {
516
+ const baseKey = normalizeAgentUrlKey(workspace.name)
517
+ ?? normalizeAgentUrlKey(asString(workspace.repoUrl)?.split("/").pop()?.replace(/\.git$/i, "") ?? "")
518
+ ?? "workspace";
519
+ return uniqueSlug(baseKey, usedKeys);
520
+ }
521
+ export function exportPortableProjectExecutionWorkspacePolicy(projectSlug, policy, workspaceKeyById, warnings) {
522
+ const next = clonePortableRecord(policy);
523
+ if (!next)
524
+ return null;
525
+ const defaultWorkspaceId = asString(next.defaultProjectWorkspaceId);
526
+ if (defaultWorkspaceId) {
527
+ const defaultWorkspaceKey = workspaceKeyById.get(defaultWorkspaceId);
528
+ if (defaultWorkspaceKey) {
529
+ next.defaultProjectWorkspaceKey = defaultWorkspaceKey;
530
+ }
531
+ else {
532
+ warnings.push(`Project ${projectSlug} default workspace ${defaultWorkspaceId} was omitted from export because that workspace is not portable.`);
533
+ }
534
+ delete next.defaultProjectWorkspaceId;
535
+ }
536
+ const cleaned = stripEmptyValues(next);
537
+ return isPlainRecord(cleaned) ? cleaned : null;
538
+ }
539
+ export function importPortableProjectExecutionWorkspacePolicy(projectSlug, policy, workspaceIdByKey, warnings) {
540
+ const next = clonePortableRecord(policy);
541
+ if (!next)
542
+ return null;
543
+ const defaultWorkspaceKey = asString(next.defaultProjectWorkspaceKey);
544
+ if (defaultWorkspaceKey) {
545
+ const defaultWorkspaceId = workspaceIdByKey.get(defaultWorkspaceKey);
546
+ if (defaultWorkspaceId) {
547
+ next.defaultProjectWorkspaceId = defaultWorkspaceId;
548
+ }
549
+ else {
550
+ warnings.push(`Project ${projectSlug} references missing workspace key ${defaultWorkspaceKey}; imported execution workspace policy without a default workspace.`);
551
+ }
552
+ }
553
+ delete next.defaultProjectWorkspaceKey;
554
+ const cleaned = stripEmptyValues(next);
555
+ return isPlainRecord(cleaned) ? cleaned : null;
556
+ }
557
+ export function stripPortableProjectExecutionWorkspaceRefs(policy) {
558
+ const next = clonePortableRecord(policy);
559
+ if (!next)
560
+ return null;
561
+ delete next.defaultProjectWorkspaceId;
562
+ delete next.defaultProjectWorkspaceKey;
563
+ const cleaned = stripEmptyValues(next);
564
+ return isPlainRecord(cleaned) ? cleaned : null;
565
+ }
566
+ export async function readGitOutput(cwd, args) {
567
+ const { stdout } = await execFileAsync("git", ["-C", cwd, ...args], { cwd });
568
+ const trimmed = stdout.trim();
569
+ return trimmed.length > 0 ? trimmed : null;
570
+ }
571
+ export async function inferPortableWorkspaceGitMetadata(workspace) {
572
+ const cwd = asString(workspace.cwd);
573
+ if (!cwd) {
574
+ return {
575
+ repoUrl: null,
576
+ repoRef: null,
577
+ defaultRef: null,
578
+ };
579
+ }
580
+ let repoUrl = null;
581
+ try {
582
+ repoUrl = await readGitOutput(cwd, ["remote", "get-url", "origin"]);
583
+ }
584
+ catch {
585
+ try {
586
+ const firstRemote = await readGitOutput(cwd, ["remote"]);
587
+ const remoteName = firstRemote?.split("\n").map((entry) => entry.trim()).find(Boolean) ?? null;
588
+ if (remoteName) {
589
+ repoUrl = await readGitOutput(cwd, ["remote", "get-url", remoteName]);
590
+ }
591
+ }
592
+ catch {
593
+ repoUrl = null;
594
+ }
595
+ }
596
+ let repoRef = null;
597
+ try {
598
+ repoRef = await readGitOutput(cwd, ["branch", "--show-current"]);
599
+ }
600
+ catch {
601
+ repoRef = null;
602
+ }
603
+ let defaultRef = null;
604
+ try {
605
+ const remoteHead = await readGitOutput(cwd, ["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"]);
606
+ defaultRef = remoteHead?.startsWith("origin/") ? remoteHead.slice("origin/".length) : remoteHead;
607
+ }
608
+ catch {
609
+ defaultRef = null;
610
+ }
611
+ return {
612
+ repoUrl,
613
+ repoRef,
614
+ defaultRef,
615
+ };
616
+ }
617
+ export async function buildPortableProjectWorkspaces(projectSlug, workspaces, warnings) {
618
+ const exportedWorkspaces = {};
619
+ const manifestWorkspaces = [];
620
+ const workspaceKeyById = new Map();
621
+ const workspaceKeyBySignature = new Map();
622
+ const manifestWorkspaceByKey = new Map();
623
+ const usedKeys = new Set();
624
+ for (const workspace of workspaces ?? []) {
625
+ const inferredGitMetadata = !asString(workspace.repoUrl) || !asString(workspace.repoRef) || !asString(workspace.defaultRef)
626
+ ? await inferPortableWorkspaceGitMetadata(workspace)
627
+ : { repoUrl: null, repoRef: null, defaultRef: null };
628
+ const repoUrl = asString(workspace.repoUrl) ?? inferredGitMetadata.repoUrl;
629
+ if (!repoUrl) {
630
+ warnings.push(`Project ${projectSlug} workspace ${workspace.name} was omitted from export because it does not have a portable repoUrl.`);
631
+ continue;
632
+ }
633
+ const repoRef = asString(workspace.repoRef) ?? inferredGitMetadata.repoRef;
634
+ const defaultRef = asString(workspace.defaultRef) ?? inferredGitMetadata.defaultRef ?? repoRef;
635
+ const workspaceSignature = JSON.stringify({
636
+ name: workspace.name,
637
+ repoUrl,
638
+ repoRef,
639
+ defaultRef,
640
+ });
641
+ const existingWorkspaceKey = workspaceKeyBySignature.get(workspaceSignature);
642
+ if (existingWorkspaceKey) {
643
+ workspaceKeyById.set(workspace.id, existingWorkspaceKey);
644
+ const existingManifestWorkspace = manifestWorkspaceByKey.get(existingWorkspaceKey);
645
+ if (existingManifestWorkspace && workspace.isPrimary) {
646
+ existingManifestWorkspace.isPrimary = true;
647
+ const existingExtensionWorkspace = exportedWorkspaces[existingWorkspaceKey];
648
+ if (isPlainRecord(existingExtensionWorkspace))
649
+ existingExtensionWorkspace.isPrimary = true;
650
+ }
651
+ continue;
652
+ }
653
+ const workspaceKey = derivePortableProjectWorkspaceKey(workspace, usedKeys);
654
+ workspaceKeyById.set(workspace.id, workspaceKey);
655
+ workspaceKeyBySignature.set(workspaceSignature, workspaceKey);
656
+ let setupCommand = asString(workspace.setupCommand);
657
+ if (setupCommand && containsAbsolutePathFragment(setupCommand)) {
658
+ warnings.push(`Project ${projectSlug} workspace ${workspaceKey} setupCommand was omitted from export because it is system-dependent.`);
659
+ setupCommand = null;
660
+ }
661
+ let cleanupCommand = asString(workspace.cleanupCommand);
662
+ if (cleanupCommand && containsAbsolutePathFragment(cleanupCommand)) {
663
+ warnings.push(`Project ${projectSlug} workspace ${workspaceKey} cleanupCommand was omitted from export because it is system-dependent.`);
664
+ cleanupCommand = null;
665
+ }
666
+ const metadata = isPlainRecord(workspace.metadata) && !containsSystemDependentPathValue(workspace.metadata)
667
+ ? workspace.metadata
668
+ : null;
669
+ if (isPlainRecord(workspace.metadata) && metadata == null) {
670
+ warnings.push(`Project ${projectSlug} workspace ${workspaceKey} metadata was omitted from export because it contains system-dependent paths.`);
671
+ }
672
+ const portableWorkspace = stripEmptyValues({
673
+ name: workspace.name,
674
+ sourceType: workspace.sourceType,
675
+ repoUrl,
676
+ repoRef,
677
+ defaultRef,
678
+ visibility: asString(workspace.visibility),
679
+ setupCommand,
680
+ cleanupCommand,
681
+ metadata,
682
+ isPrimary: workspace.isPrimary ? true : undefined,
683
+ });
684
+ if (!isPlainRecord(portableWorkspace))
685
+ continue;
686
+ exportedWorkspaces[workspaceKey] = portableWorkspace;
687
+ const manifestWorkspace = {
688
+ key: workspaceKey,
689
+ name: workspace.name,
690
+ sourceType: asString(workspace.sourceType),
691
+ repoUrl,
692
+ repoRef,
693
+ defaultRef,
694
+ visibility: asString(workspace.visibility),
695
+ setupCommand,
696
+ cleanupCommand,
697
+ metadata,
698
+ isPrimary: workspace.isPrimary,
699
+ };
700
+ manifestWorkspaces.push(manifestWorkspace);
701
+ manifestWorkspaceByKey.set(workspaceKey, manifestWorkspace);
702
+ }
703
+ return {
704
+ extension: Object.keys(exportedWorkspaces).length > 0 ? exportedWorkspaces : undefined,
705
+ manifest: manifestWorkspaces,
706
+ workspaceKeyById,
707
+ };
708
+ }
709
+ export const WEEKDAY_TO_CRON = {
710
+ sunday: "0",
711
+ monday: "1",
712
+ tuesday: "2",
713
+ wednesday: "3",
714
+ thursday: "4",
715
+ friday: "5",
716
+ saturday: "6",
717
+ };
718
+ export function readZonedDateParts(startsAt, timeZone) {
719
+ try {
720
+ const date = new Date(startsAt);
721
+ if (Number.isNaN(date.getTime()))
722
+ return null;
723
+ const formatter = new Intl.DateTimeFormat("en-US", {
724
+ timeZone,
725
+ hour12: false,
726
+ weekday: "long",
727
+ month: "numeric",
728
+ day: "numeric",
729
+ hour: "numeric",
730
+ minute: "numeric",
731
+ });
732
+ const parts = Object.fromEntries(formatter
733
+ .formatToParts(date)
734
+ .filter((entry) => entry.type !== "literal")
735
+ .map((entry) => [entry.type, entry.value]));
736
+ const weekday = WEEKDAY_TO_CRON[parts.weekday?.toLowerCase() ?? ""];
737
+ const month = Number(parts.month);
738
+ const day = Number(parts.day);
739
+ const hour = Number(parts.hour);
740
+ const minute = Number(parts.minute);
741
+ if (!weekday || !Number.isFinite(month) || !Number.isFinite(day) || !Number.isFinite(hour) || !Number.isFinite(minute)) {
742
+ return null;
743
+ }
744
+ return { weekday, month, day, hour, minute };
745
+ }
746
+ catch {
747
+ return null;
748
+ }
749
+ }
750
+ export function normalizeCronList(values) {
751
+ return Array.from(new Set(values)).sort((left, right) => Number(left) - Number(right)).join(",");
752
+ }
753
+ export function buildLegacyAutomationTriggerFromRecurrence(issue, scheduleValue) {
754
+ const warnings = [];
755
+ const errors = [];
756
+ if (!issue.legacyRecurrence || !isPlainRecord(issue.legacyRecurrence)) {
757
+ return { trigger: null, warnings, errors };
758
+ }
759
+ const schedule = isPlainRecord(scheduleValue) ? scheduleValue : null;
760
+ const frequency = asString(issue.legacyRecurrence.frequency);
761
+ const interval = asInteger(issue.legacyRecurrence.interval) ?? 1;
762
+ if (!frequency) {
763
+ errors.push(`Recurring task ${issue.slug} uses legacy recurrence without frequency; add .rudder.yaml automations.${issue.slug}.triggers.`);
764
+ return { trigger: null, warnings, errors };
765
+ }
766
+ if (interval < 1) {
767
+ errors.push(`Recurring task ${issue.slug} uses legacy recurrence with an invalid interval; add .rudder.yaml automations.${issue.slug}.triggers.`);
768
+ return { trigger: null, warnings, errors };
769
+ }
770
+ const timezone = asString(schedule?.timezone) ?? "UTC";
771
+ const startsAt = asString(schedule?.startsAt);
772
+ const zonedStartsAt = startsAt ? readZonedDateParts(startsAt, timezone) : null;
773
+ if (startsAt && !zonedStartsAt) {
774
+ errors.push(`Recurring task ${issue.slug} has an invalid legacy startsAt/timezone combination; add .rudder.yaml automations.${issue.slug}.triggers.`);
775
+ return { trigger: null, warnings, errors };
776
+ }
777
+ const time = isPlainRecord(issue.legacyRecurrence.time) ? issue.legacyRecurrence.time : null;
778
+ const hour = asInteger(time?.hour) ?? zonedStartsAt?.hour ?? 0;
779
+ const minute = asInteger(time?.minute) ?? zonedStartsAt?.minute ?? 0;
780
+ if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
781
+ errors.push(`Recurring task ${issue.slug} uses legacy recurrence with an invalid time; add .rudder.yaml automations.${issue.slug}.triggers.`);
782
+ return { trigger: null, warnings, errors };
783
+ }
784
+ if (issue.legacyRecurrence.until != null || issue.legacyRecurrence.count != null) {
785
+ warnings.push(`Recurring task ${issue.slug} uses legacy recurrence end bounds; Rudder will import the automation trigger without those limits.`);
786
+ }
787
+ let cronExpression = null;
788
+ if (frequency === "hourly") {
789
+ const hourField = interval === 1
790
+ ? "*"
791
+ : zonedStartsAt
792
+ ? `${zonedStartsAt.hour}-23/${interval}`
793
+ : `*/${interval}`;
794
+ cronExpression = `${minute} ${hourField} * * *`;
795
+ }
796
+ else if (frequency === "daily") {
797
+ if (Array.isArray(issue.legacyRecurrence.weekdays) || Array.isArray(issue.legacyRecurrence.monthDays) || Array.isArray(issue.legacyRecurrence.months)) {
798
+ errors.push(`Recurring task ${issue.slug} uses unsupported legacy daily recurrence constraints; add .rudder.yaml automations.${issue.slug}.triggers.`);
799
+ return { trigger: null, warnings, errors };
800
+ }
801
+ const dayField = interval === 1 ? "*" : `*/${interval}`;
802
+ cronExpression = `${minute} ${hour} ${dayField} * *`;
803
+ }
804
+ else if (frequency === "weekly") {
805
+ if (interval !== 1) {
806
+ errors.push(`Recurring task ${issue.slug} uses legacy weekly recurrence with interval > 1; add .rudder.yaml automations.${issue.slug}.triggers.`);
807
+ return { trigger: null, warnings, errors };
808
+ }
809
+ const weekdays = Array.isArray(issue.legacyRecurrence.weekdays)
810
+ ? issue.legacyRecurrence.weekdays
811
+ .map((entry) => asString(entry))
812
+ .filter((entry) => Boolean(entry))
813
+ : [];
814
+ const cronWeekdays = weekdays
815
+ .map((entry) => WEEKDAY_TO_CRON[entry.toLowerCase()])
816
+ .filter((entry) => Boolean(entry));
817
+ if (cronWeekdays.length === 0 && zonedStartsAt?.weekday) {
818
+ cronWeekdays.push(zonedStartsAt.weekday);
819
+ }
820
+ if (cronWeekdays.length === 0) {
821
+ errors.push(`Recurring task ${issue.slug} uses legacy weekly recurrence without weekdays; add .rudder.yaml automations.${issue.slug}.triggers.`);
822
+ return { trigger: null, warnings, errors };
823
+ }
824
+ cronExpression = `${minute} ${hour} * * ${normalizeCronList(cronWeekdays)}`;
825
+ }
826
+ else if (frequency === "monthly") {
827
+ if (interval !== 1) {
828
+ errors.push(`Recurring task ${issue.slug} uses legacy monthly recurrence with interval > 1; add .rudder.yaml automations.${issue.slug}.triggers.`);
829
+ return { trigger: null, warnings, errors };
830
+ }
831
+ if (Array.isArray(issue.legacyRecurrence.ordinalWeekdays) && issue.legacyRecurrence.ordinalWeekdays.length > 0) {
832
+ errors.push(`Recurring task ${issue.slug} uses legacy ordinal monthly recurrence; add .rudder.yaml automations.${issue.slug}.triggers.`);
833
+ return { trigger: null, warnings, errors };
834
+ }
835
+ const monthDays = Array.isArray(issue.legacyRecurrence.monthDays)
836
+ ? issue.legacyRecurrence.monthDays
837
+ .map((entry) => asInteger(entry))
838
+ .filter((entry) => entry != null && entry >= 1 && entry <= 31)
839
+ : [];
840
+ if (monthDays.length === 0 && zonedStartsAt?.day) {
841
+ monthDays.push(zonedStartsAt.day);
842
+ }
843
+ if (monthDays.length === 0) {
844
+ errors.push(`Recurring task ${issue.slug} uses legacy monthly recurrence without monthDays; add .rudder.yaml automations.${issue.slug}.triggers.`);
845
+ return { trigger: null, warnings, errors };
846
+ }
847
+ const months = Array.isArray(issue.legacyRecurrence.months)
848
+ ? issue.legacyRecurrence.months
849
+ .map((entry) => asInteger(entry))
850
+ .filter((entry) => entry != null && entry >= 1 && entry <= 12)
851
+ : [];
852
+ const monthField = months.length > 0 ? normalizeCronList(months.map(String)) : "*";
853
+ cronExpression = `${minute} ${hour} ${normalizeCronList(monthDays.map(String))} ${monthField} *`;
854
+ }
855
+ else if (frequency === "yearly") {
856
+ if (interval !== 1) {
857
+ errors.push(`Recurring task ${issue.slug} uses legacy yearly recurrence with interval > 1; add .rudder.yaml automations.${issue.slug}.triggers.`);
858
+ return { trigger: null, warnings, errors };
859
+ }
860
+ const months = Array.isArray(issue.legacyRecurrence.months)
861
+ ? issue.legacyRecurrence.months
862
+ .map((entry) => asInteger(entry))
863
+ .filter((entry) => entry != null && entry >= 1 && entry <= 12)
864
+ : [];
865
+ if (months.length === 0 && zonedStartsAt?.month) {
866
+ months.push(zonedStartsAt.month);
867
+ }
868
+ const monthDays = Array.isArray(issue.legacyRecurrence.monthDays)
869
+ ? issue.legacyRecurrence.monthDays
870
+ .map((entry) => asInteger(entry))
871
+ .filter((entry) => entry != null && entry >= 1 && entry <= 31)
872
+ : [];
873
+ if (monthDays.length === 0 && zonedStartsAt?.day) {
874
+ monthDays.push(zonedStartsAt.day);
875
+ }
876
+ if (months.length === 0 || monthDays.length === 0) {
877
+ errors.push(`Recurring task ${issue.slug} uses legacy yearly recurrence without month/monthDay anchors; add .rudder.yaml automations.${issue.slug}.triggers.`);
878
+ return { trigger: null, warnings, errors };
879
+ }
880
+ cronExpression = `${minute} ${hour} ${normalizeCronList(monthDays.map(String))} ${normalizeCronList(months.map(String))} *`;
881
+ }
882
+ else {
883
+ errors.push(`Recurring task ${issue.slug} uses unsupported legacy recurrence frequency "${frequency}"; add .rudder.yaml automations.${issue.slug}.triggers.`);
884
+ return { trigger: null, warnings, errors };
885
+ }
886
+ return {
887
+ trigger: {
888
+ kind: "schedule",
889
+ label: "Migrated legacy recurrence",
890
+ enabled: true,
891
+ cronExpression,
892
+ timezone,
893
+ signingMode: null,
894
+ replayWindowSec: null,
895
+ },
896
+ warnings,
897
+ errors,
898
+ };
899
+ }
900
+ export function resolvePortableAutomationDefinition(issue, scheduleValue) {
901
+ const warnings = [];
902
+ const errors = [];
903
+ if (!issue.recurring) {
904
+ return { automation: null, warnings, errors };
905
+ }
906
+ const automation = issue.automation
907
+ ? {
908
+ concurrencyPolicy: issue.automation.concurrencyPolicy,
909
+ catchUpPolicy: issue.automation.catchUpPolicy,
910
+ triggers: [...issue.automation.triggers],
911
+ }
912
+ : {
913
+ concurrencyPolicy: null,
914
+ catchUpPolicy: null,
915
+ triggers: [],
916
+ };
917
+ if (automation.concurrencyPolicy && !AUTOMATION_CONCURRENCY_POLICIES.includes(automation.concurrencyPolicy)) {
918
+ errors.push(`Recurring task ${issue.slug} uses unsupported automation concurrencyPolicy "${automation.concurrencyPolicy}".`);
919
+ }
920
+ if (automation.catchUpPolicy && !AUTOMATION_CATCH_UP_POLICIES.includes(automation.catchUpPolicy)) {
921
+ errors.push(`Recurring task ${issue.slug} uses unsupported automation catchUpPolicy "${automation.catchUpPolicy}".`);
922
+ }
923
+ for (const trigger of automation.triggers) {
924
+ if (!AUTOMATION_TRIGGER_KINDS.includes(trigger.kind)) {
925
+ errors.push(`Recurring task ${issue.slug} uses unsupported trigger kind "${trigger.kind}".`);
926
+ continue;
927
+ }
928
+ if (trigger.kind === "schedule") {
929
+ if (!trigger.cronExpression || !trigger.timezone) {
930
+ errors.push(`Recurring task ${issue.slug} has a schedule trigger missing cronExpression/timezone.`);
931
+ continue;
932
+ }
933
+ const cronError = validateCron(trigger.cronExpression);
934
+ if (cronError) {
935
+ errors.push(`Recurring task ${issue.slug} has an invalid schedule trigger: ${cronError}`);
936
+ }
937
+ continue;
938
+ }
939
+ if (trigger.kind === "webhook" && trigger.signingMode && !AUTOMATION_TRIGGER_SIGNING_MODES.includes(trigger.signingMode)) {
940
+ errors.push(`Recurring task ${issue.slug} uses unsupported webhook signingMode "${trigger.signingMode}".`);
941
+ }
942
+ }
943
+ if (automation.triggers.length === 0 && issue.legacyRecurrence) {
944
+ const migrated = buildLegacyAutomationTriggerFromRecurrence(issue, scheduleValue);
945
+ warnings.push(...migrated.warnings);
946
+ errors.push(...migrated.errors);
947
+ if (migrated.trigger) {
948
+ automation.triggers.push(migrated.trigger);
949
+ }
950
+ }
951
+ return { automation, warnings, errors };
952
+ }
953
+ export function toSafeSlug(input, fallback) {
954
+ return normalizeAgentUrlKey(input) ?? fallback;
955
+ }
956
+ export function uniqueSlug(base, used) {
957
+ if (!used.has(base)) {
958
+ used.add(base);
959
+ return base;
960
+ }
961
+ let idx = 2;
962
+ while (true) {
963
+ const candidate = `${base}-${idx}`;
964
+ if (!used.has(candidate)) {
965
+ used.add(candidate);
966
+ return candidate;
967
+ }
968
+ idx += 1;
969
+ }
970
+ }
971
+ export function uniqueNameBySlug(baseName, existingSlugs) {
972
+ const baseSlug = normalizeAgentUrlKey(baseName) ?? "agent";
973
+ if (!existingSlugs.has(baseSlug))
974
+ return baseName;
975
+ let idx = 2;
976
+ while (true) {
977
+ const candidateName = `${baseName} ${idx}`;
978
+ const candidateSlug = normalizeAgentUrlKey(candidateName) ?? `agent-${idx}`;
979
+ if (!existingSlugs.has(candidateSlug))
980
+ return candidateName;
981
+ idx += 1;
982
+ }
983
+ }
984
+ export function uniqueProjectName(baseName, existingProjectSlugs) {
985
+ const baseSlug = deriveProjectUrlKey(baseName, baseName);
986
+ if (!existingProjectSlugs.has(baseSlug))
987
+ return baseName;
988
+ let idx = 2;
989
+ while (true) {
990
+ const candidateName = `${baseName} ${idx}`;
991
+ const candidateSlug = deriveProjectUrlKey(candidateName, candidateName);
992
+ if (!existingProjectSlugs.has(candidateSlug))
993
+ return candidateName;
994
+ idx += 1;
995
+ }
996
+ }
997
+ //# sourceMappingURL=organization-portability.core.js.map