@desplega.ai/agent-swarm 2.4.5 → 2.5.1

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 (275) hide show
  1. package/README.md +4 -2
  2. package/dist/{acp-adapter-2wdkktv6.js → acp-adapter-7g6bpwbk.js} +8 -6
  3. package/dist/{actions-c40ebcm4.js → actions-w8xd014k.js} +23 -21
  4. package/dist/{amp-adapter-wb67m95z.js → amp-adapter-z4qvhacj.js} +2 -2
  5. package/dist/{anthropic-messages-g6pqmqk4.js → anthropic-messages-txs190dd.js} +17 -20
  6. package/dist/{app-353vre8g.js → app-nndcvftq.js} +3 -3
  7. package/dist/{assistant-sj1njh23.js → assistant-hjmqyscx.js} +24 -22
  8. package/dist/{azure-openai-responses-9dbmj346.js → azure-openai-responses-9kfwhmn7.js} +18 -13
  9. package/dist/{boot-reembed-b9c3az3c.js → boot-reembed-r8rhf9h8.js} +1 -1
  10. package/dist/{boot-reembed-qdkvxeem.js → boot-reembed-vwcj2y5d.js} +1 -1
  11. package/dist/{boot-scrub-sweep-m3wh8eks.js → boot-scrub-sweep-fr9q36ne.js} +4 -4
  12. package/dist/{boot-seeds-j2273s54.js → boot-seeds-9jqwnegq.js} +4 -4
  13. package/dist/{claude-adapter-m7q0a085.js → claude-adapter-2f8b85df.js} +8 -6
  14. package/dist/{claude-managed-adapter-5ptb6tzs.js → claude-managed-adapter-gt6pa35d.js} +2 -2
  15. package/dist/{claude-managed-setup-smrqk5j5.js → claude-managed-setup-c3hp36ph.js} +4 -4
  16. package/dist/{claude-sdk-session-38xnz21e.js → claude-sdk-session-05kat8rv.js} +9012 -8928
  17. package/dist/{cli-b9fcxxev.js → cli-007cnhm1.js} +50 -4
  18. package/dist/{cli-j4rqdf2n.js → cli-03vpq45j.js} +2 -2
  19. package/dist/{cli-1sp861s4.js → cli-0jy85zz4.js} +11 -11
  20. package/dist/{cli-j99azg3g.js → cli-1dp1zj04.js} +5 -5
  21. package/dist/{cli-3r8samv3.js → cli-1f0gp9vz.js} +3 -2
  22. package/dist/{cli-94gwyg7m.js → cli-22rmcjkg.js} +9 -9
  23. package/dist/{cli-ms85309d.js → cli-2jg61wab.js} +11 -11
  24. package/dist/{cli-0bqteszy.js → cli-2nf3b08t.js} +328 -25
  25. package/dist/{cli-9yqgm9nd.js → cli-2wba1ac9.js} +161 -63
  26. package/dist/{cli-cxxe61f6.js → cli-3ee5z0q0.js} +2 -2
  27. package/dist/{cli-k8g16gz3.js → cli-3qv8naq8.js} +115 -119
  28. package/dist/{cli-60cgh1rv.js → cli-459fk97x.js} +7 -7
  29. package/dist/{cli-h7gc0b4r.js → cli-5m84zd2k.js} +55 -18
  30. package/dist/{cli-dvkmp9bt.js → cli-6ctwrf1z.js} +20 -10
  31. package/dist/{cli-848hxdwj.js → cli-6rg2jn2y.js} +2 -1
  32. package/dist/{cli-dk44dxec.js → cli-9mm5ade4.js} +1 -1
  33. package/dist/{cli-7c9qs530.js → cli-ajqhxtnz.js} +5 -5
  34. package/dist/{cli-be2161h1.js → cli-cah5detr.js} +6 -6
  35. package/dist/{cli-v8fjakwf.js → cli-cwyafhw1.js} +1 -1
  36. package/dist/{cli-wxbn3yfx.js → cli-cz5nmdxt.js} +2 -2
  37. package/dist/{cli-wt645v7q.js → cli-dabehxhp.js} +1 -1
  38. package/dist/{cli-vfha21c9.js → cli-e5bxnjps.js} +2 -2
  39. package/dist/{cli-37j04k05.js → cli-e9btqw4y.js} +13 -13
  40. package/dist/{cli-1syn2xy1.js → cli-eym3jg7w.js} +32 -18
  41. package/dist/{cli-ftc1g5tj.js → cli-fes51ya2.js} +3 -3
  42. package/dist/{cli-s95dknxh.js → cli-g1cw7xtt.js} +1 -1
  43. package/dist/{cli-74c1wpm0.js → cli-gpv60278.js} +1 -1
  44. package/dist/{cli-1f3qzw6y.js → cli-gwcf52gz.js} +2 -2
  45. package/dist/{cli-pemywhfq.js → cli-ha9rmwgq.js} +2 -1
  46. package/dist/{cli-v0yrfmdh.js → cli-hadv0725.js} +3 -3
  47. package/dist/{cli-g35m2xwm.js → cli-j1eghqfm.js} +2 -2
  48. package/dist/{cli-qfxc84gh.js → cli-jpxsrxcb.js} +1 -1
  49. package/dist/{cli-n72rg53p.js → cli-kcsd1ez8.js} +848 -426
  50. package/dist/{cli-ejs3m1sx.js → cli-kxpfx2xr.js} +1 -1
  51. package/dist/{cli-pnp2j5zg.js → cli-mmhj8vd7.js} +2 -2
  52. package/dist/{cli-st8aw1m6.js → cli-mq7kg1b1.js} +4 -4
  53. package/dist/{cli-bnes4z6b.js → cli-mz2ygeyq.js} +3 -3
  54. package/dist/{cli-xf234ws8.js → cli-n4c8e3s5.js} +2 -0
  55. package/dist/{cli-f01h25yt.js → cli-n6kmqngw.js} +2 -2
  56. package/dist/cli-nj12tn2c.js +1193 -0
  57. package/dist/{cli-1dmcq2eh.js → cli-nzfnt2gs.js} +1 -1
  58. package/dist/{cli-625tb7aq.js → cli-p859hcc8.js} +2 -2
  59. package/dist/{cli-smvcw9z5.js → cli-pasyvjmm.js} +1 -1
  60. package/dist/cli-pkaqk57w.js +128 -0
  61. package/dist/{cli-xpa64rek.js → cli-pyy4c9ch.js} +2362 -159
  62. package/dist/{cli-wt0jf9hm.js → cli-q9pzwxvk.js} +553 -193
  63. package/dist/{cli-z7d29rw9.js → cli-qfjm4gvt.js} +4 -4
  64. package/dist/{cli-p14m2cnp.js → cli-qfm6my86.js} +1 -1
  65. package/dist/{cli-8nyhf7za.js → cli-qqzmjxkf.js} +129 -105
  66. package/dist/{cli-4zfqgjc5.js → cli-r9fy0ddc.js} +2 -2
  67. package/dist/{cli-eww120g8.js → cli-rh5smt8t.js} +18 -4
  68. package/dist/{cli-a92r1127.js → cli-rngde2jv.js} +2 -2
  69. package/dist/{cli-qwkcwjdn.js → cli-rycdaj0a.js} +1 -1
  70. package/dist/{cli-fv5hepyy.js → cli-sn1vbtg2.js} +3 -3
  71. package/dist/{cli-36ckw0wx.js → cli-stxdrqs2.js} +2 -2
  72. package/dist/{cli-1m17dc9d.js → cli-ta8bd7th.js} +2 -2
  73. package/dist/{cli-43x64hv3.js → cli-v2g93k4v.js} +4 -4
  74. package/dist/{cli-d2mb5s8a.js → cli-x77gen2p.js} +680 -440
  75. package/dist/{cli-3a45zcgm.js → cli-xc65x52q.js} +2 -2
  76. package/dist/{cli-f0g3pgvf.js → cli-xd4eqtr2.js} +2 -2
  77. package/dist/{cli-018r4jq6.js → cli-y3zyaee5.js} +8 -8
  78. package/dist/{cli-kpw04va0.js → cli-z2dv25mf.js} +1 -1
  79. package/dist/{cli-qwhy2qma.js → cli-z63a269p.js} +2 -2
  80. package/dist/{cli-sm8rses9.js → cli-zfdp01hn.js} +8 -5
  81. package/dist/{cli-tw4p90jb.js → cli-znvq0k3t.js} +5 -5
  82. package/dist/cli.js +29 -27
  83. package/dist/{cloudflare-workers-ai-system-one-ch2wxfcp.js → cloudflare-workers-ai-system-one-43v9qkjk.js} +7 -2
  84. package/dist/{codex-adapter-tn6k5mkg.js → codex-adapter-p4ptwar5.js} +6 -4
  85. package/dist/{codex-login-m819c41r.js → codex-login-rn7c5gxt.js} +1 -1
  86. package/dist/{codex-session-runner-7vjt7jbw.js → codex-session-runner-964c7dnk.js} +7 -5
  87. package/dist/{commands-t7rz9146.js → commands-mbvhbrcy.js} +2 -2
  88. package/dist/{controller-m2jasma5.js → controller-gnq1k1mf.js} +4 -4
  89. package/dist/{controllers-connect-9ftpex99.js → controllers-connect-6dkm71tg.js} +25 -23
  90. package/dist/{cursor-adapter-mjv79e4z.js → cursor-adapter-yq5xgfcg.js} +1 -1
  91. package/dist/{db-6sfrn9g3.js → db-88wcymxt.js} +14 -2
  92. package/dist/{db-rn673r06.js → db-af9y8nkf.js} +3 -3
  93. package/dist/{devin-adapter-zgqadvnm.js → devin-adapter-4ycy4vrf.js} +1 -1
  94. package/dist/{dispatcher-c155xz0p.js → dispatcher-606ydx5v.js} +22 -20
  95. package/dist/{docker-fkgtr75t.js → docker-nfy2gc8t.js} +2 -2
  96. package/dist/{dsh-adapter-3mmszc1x.js → dsh-adapter-tvhc4k2d.js} +1 -1
  97. package/dist/{e2b-16d6ch39.js → e2b-9gkdhm3c.js} +2 -2
  98. package/dist/{e2b-zn0b4w5w.js → e2b-cjtf8k1z.js} +2 -2
  99. package/dist/{easter-egg-3d-5cgynaja.js → easter-egg-3d-e4qv8dxj.js} +1 -1
  100. package/dist/{event-bus-9vpk8gmq.js → event-bus-3z78ep5n.js} +1 -1
  101. package/dist/{execute-t4e6m3rw.js → execute-0xpz8950.js} +85 -23
  102. package/dist/{external-channel-35k6tkv8.js → external-channel-y8q5z8z2.js} +2 -2
  103. package/dist/{google-generative-ai-bmq8gkf3.js → google-generative-ai-mk9vcpe1.js} +15 -15
  104. package/dist/{google-vertex-b1rvp52s.js → google-vertex-q580kz8k.js} +20 -20
  105. package/dist/{grok-adapter-tfrq7tg1.js → grok-adapter-39aha52t.js} +9 -7
  106. package/dist/handlers-rk9dqech.js +41 -0
  107. package/dist/{heartbeat-dyg4npkp.js → heartbeat-jfe9zfjr.js} +25 -23
  108. package/dist/{hook-drspbwpe.js → hook-b1mez1m8.js} +9 -7
  109. package/dist/{hook-x26b31bg.js → hook-ffevzed1.js} +7 -5
  110. package/dist/{http-pk972xyw.js → http-d5b44f1r.js} +544 -76
  111. package/dist/{index-g6tbb6ve.js → index-31ceyf42.js} +1 -1
  112. package/dist/index-4q3vj1yr.js +46 -0
  113. package/dist/{index-arytgj5q.js → index-5en23s5z.js} +1 -1
  114. package/dist/index-d2qeem97.js +42 -0
  115. package/dist/index-mj46rk9k.js +43 -0
  116. package/dist/{index-jwxkkex2.js → index-nq8hhv28.js} +13 -11
  117. package/dist/{index-g216q6jr.js → index-zsyx51ap.js} +1 -4
  118. package/dist/{keepalive-7yrng7px.js → keepalive-wsby1btq.js} +4 -4
  119. package/dist/lead-paa141j6.js +79 -0
  120. package/dist/{llama-cpp-classify-vv43gswy.js → llama-cpp-classify-ee7vmd7q.js} +4 -1
  121. package/dist/{maintenance-e6cemdqt.js → maintenance-vnshcyv9.js} +1 -1
  122. package/dist/{mistral-conversations-1medfwv7.js → mistral-conversations-sd0xf1tn.js} +13 -13
  123. package/dist/{node-de6akczr.js → node-jzjj7r9x.js} +1 -1
  124. package/dist/{oauth-refresh-sweep-yw3xdbcj.js → oauth-refresh-sweep-d6sqn5np.js} +3 -3
  125. package/dist/{onboard-0a9y5yrc.js → onboard-nr4xhpzy.js} +2 -2
  126. package/dist/{openai-codex-responses-de9pvs4d.js → openai-codex-responses-79s8xnbh.js} +29 -23
  127. package/dist/{openai-completions-mtqge3nf.js → openai-completions-tdbyts0x.js} +21 -20
  128. package/dist/{openai-decisions-ygk4kkxd.js → openai-decisions-bqhnjyfz.js} +2 -1
  129. package/dist/{openai-responses-dkyng71g.js → openai-responses-dm3t5vqp.js} +26 -17
  130. package/dist/{opencode-adapter-x4tqzhkh.js → opencode-adapter-e56086m1.js} +7 -5
  131. package/dist/{openrouter-images-wvv7camj.js → openrouter-images-ssttr1y4.js} +6 -3
  132. package/dist/{otel-impl-trjpkfb7.js → otel-impl-ytn9wyv9.js} +2 -2
  133. package/dist/{pi-messages-nhh1pkz2.js → pi-messages-3nf8bq1a.js} +6 -4
  134. package/dist/{pi-mono-adapter-mcfkn9vf.js → pi-mono-adapter-tzps8f38.js} +9 -37
  135. package/dist/{pricing-refresh-d2b5my0y.js → pricing-refresh-pva04zee.js} +3 -3
  136. package/dist/{rbac-roles-nxh5ahwk.js → rbac-roles-7rc1q3g4.js} +1 -1
  137. package/dist/{rbac-roles-hey3yv9d.js → rbac-roles-ff1ffmec.js} +2 -2
  138. package/dist/{render-v2-rr3p2atg.js → render-v2-pyfsg9zk.js} +3 -3
  139. package/dist/{resume-2efkf1s1.js → resume-phj8xhqr.js} +10 -8
  140. package/dist/{runtime-xe3aqy4x.js → runtime-bt5pkpm1.js} +1 -1
  141. package/dist/{session-access-s2mttxpw.js → session-access-jzx2z9h5.js} +6 -4
  142. package/dist/{setup-vypma5yt.js → setup-rfg0f0sg.js} +1 -1
  143. package/dist/{typesafe-system-one-2hgpayzy.js → typesafe-system-one-bre38hvs.js} +4 -2
  144. package/dist/{virtual-modules-4r3zkc20.js → virtual-modules-mnfbh5mr.js} +8 -2
  145. package/dist/{work-objects-rvhckdkp.js → work-objects-44z2yjg8.js} +25 -23
  146. package/dist/worker-zsfqzxhm.js +79 -0
  147. package/dist/{x-y45mthwn.js → x-pbpezr0s.js} +2 -2
  148. package/openapi.json +785 -5
  149. package/package.json +9 -9
  150. package/src/assets/key.ts +17 -0
  151. package/src/azure-devops/handlers.ts +1 -1
  152. package/src/be/db/approvals.ts +18 -0
  153. package/src/be/db/session-moves.ts +164 -0
  154. package/src/be/db/session-tree.ts +384 -0
  155. package/src/be/db/tasks/read.ts +40 -4
  156. package/src/be/db/workflow-runs.ts +96 -0
  157. package/src/be/db.ts +80 -236
  158. package/src/be/onboarding.ts +3 -0
  159. package/src/be/skill-sync.ts +43 -2
  160. package/src/be/swarm-config-guard.ts +1 -0
  161. package/src/bitbucket/api.ts +81 -0
  162. package/src/bitbucket/auth.ts +64 -0
  163. package/src/bitbucket/handlers.ts +434 -0
  164. package/src/bitbucket/index.ts +28 -0
  165. package/src/bitbucket/templates.ts +134 -0
  166. package/src/bitbucket/types.ts +65 -0
  167. package/src/commands/runner.ts +55 -3
  168. package/src/e2b/env.ts +1 -0
  169. package/src/extensions/contract-types.generated.ts +1 -1
  170. package/src/extensions/contract.ts +2 -2
  171. package/src/extensions/post-bridge.ts +1 -0
  172. package/src/github/handlers.ts +6 -6
  173. package/src/gitlab/auth.ts +8 -2
  174. package/src/gitlab/handlers.ts +63 -15
  175. package/src/gitlab/index.ts +1 -1
  176. package/src/http/assets.ts +14 -2
  177. package/src/http/core.ts +12 -0
  178. package/src/http/index.ts +4 -0
  179. package/src/http/onboarding.ts +1 -0
  180. package/src/http/sessions.ts +366 -12
  181. package/src/http/skills.ts +48 -1
  182. package/src/http/tasks.ts +1 -1
  183. package/src/http/users.ts +1 -0
  184. package/src/http/webhooks.ts +141 -0
  185. package/src/integrations/chat-sdk/adapters.ts +19 -3
  186. package/src/integrations/chat-sdk/facts.ts +30 -12
  187. package/src/integrations/chat-sdk/outbound.ts +38 -1
  188. package/src/providers/acp-targets.ts +1 -1
  189. package/src/providers/amp-adapter.ts +1 -1
  190. package/src/providers/pi-mono-adapter.ts +5 -53
  191. package/src/scripts-runtime/types/swarm-extension.d.ts +6 -4
  192. package/src/slack/handlers.test.ts +158 -0
  193. package/src/slack/handlers.ts +19 -28
  194. package/src/tasks/context-key.ts +61 -1
  195. package/src/tests/bitbucket-auth.test.ts +156 -0
  196. package/src/tests/bitbucket-handlers.test.ts +425 -0
  197. package/src/tests/bitbucket-webhook.test.ts +220 -0
  198. package/src/tests/chat-sdk-inbound.test.ts +39 -0
  199. package/src/tests/chat-sdk-telegram-markdown.test.ts +92 -0
  200. package/src/tests/context-key.test.ts +50 -0
  201. package/src/tests/core-auth.test.ts +5 -0
  202. package/src/tests/db-task-read-contract.test.ts +7 -0
  203. package/src/tests/db-task-write-contract.test.ts +6 -0
  204. package/src/tests/docs-index-footprint.test.js +3 -3
  205. package/src/tests/fixtures/bitbucket/pullrequest-comment-created-inline.json +174 -0
  206. package/src/tests/fixtures/bitbucket/pullrequest-comment-created.json +170 -0
  207. package/src/tests/fixtures/bitbucket/pullrequest-created-mention.json +132 -0
  208. package/src/tests/fixtures/bitbucket/pullrequest-created-reviewer.json +140 -0
  209. package/src/tests/fixtures/bitbucket/pullrequest-fulfilled.json +134 -0
  210. package/src/tests/fixtures/bitbucket/pullrequest-rejected.json +133 -0
  211. package/src/tests/generate-mcp-docs.test.ts +101 -0
  212. package/src/tests/gitlab-auth.test.ts +13 -5
  213. package/src/tests/gitlab-handlers.test.ts +273 -25
  214. package/src/tests/gitlab-vcs-db.test.ts +4 -4
  215. package/src/tests/integration-disable-flags.test.ts +36 -0
  216. package/src/tests/mcp-tools.test.ts +1 -1
  217. package/src/tests/onboarding.test.ts +12 -0
  218. package/src/tests/pi-codemode.test.ts +8 -2
  219. package/src/tests/preload-env.test.ts +57 -0
  220. package/src/tests/preload.ts +21 -0
  221. package/src/tests/prompt-template-remaining.test.ts +38 -0
  222. package/src/tests/run-root-coverage.test.ts +39 -0
  223. package/src/tests/runner-bitbucket-vcs.test.ts +191 -0
  224. package/src/tests/runner-skills-refresh.test.ts +58 -0
  225. package/src/tests/secret-scrubber.test.ts +15 -0
  226. package/src/tests/sessions-move.test.ts +576 -0
  227. package/src/tests/sessions-tree.test.ts +493 -0
  228. package/src/tests/skill-files-http.test.ts +50 -0
  229. package/src/tests/skills-bundle.test.ts +99 -0
  230. package/src/tests/swarm-config-export-to-env.test.ts +2 -1
  231. package/src/tests/vcs-bitbucket.test.ts +91 -0
  232. package/src/tests/vcs-provider-isolation.test.ts +123 -0
  233. package/src/tests/vcs-provider.test.ts +16 -1
  234. package/src/tests/vcs-tracking.test.ts +3 -3
  235. package/src/tests/workflow-foreach-bodies.test.ts +637 -0
  236. package/src/tests/workflow-foreach-concurrency.test.ts +342 -0
  237. package/src/tests/workflow-foreach-retry.test.ts +537 -0
  238. package/src/tests/workflow-foreach.test.ts +44 -23
  239. package/src/tests/workflow-step-claims.test.ts +6 -6
  240. package/src/tests/workflow-tla-races.test.ts +2 -2
  241. package/src/tools/script-delete.ts +1 -1
  242. package/src/tools/workflows/create-workflow.ts +5 -3
  243. package/src/types.ts +3 -2
  244. package/src/utils/config-env-export.ts +1 -0
  245. package/src/utils/secret-scrubber.ts +4 -0
  246. package/src/utils/skills-refresh.ts +83 -43
  247. package/src/vcs/bitbucket.ts +58 -0
  248. package/src/vcs/index.ts +2 -0
  249. package/src/vcs/types.ts +2 -2
  250. package/src/workflows/approval-resolution.ts +4 -1
  251. package/src/workflows/checkpoint.ts +9 -1
  252. package/src/workflows/constants.ts +3 -0
  253. package/src/workflows/definition.ts +48 -17
  254. package/src/workflows/engine.ts +25 -15
  255. package/src/workflows/executors/foreach.ts +45 -99
  256. package/src/workflows/foreach-body.ts +146 -0
  257. package/src/workflows/foreach-driver.ts +552 -0
  258. package/src/workflows/foreach-join.ts +206 -7
  259. package/src/workflows/node-timeout.ts +21 -0
  260. package/src/workflows/recovery.ts +68 -3
  261. package/src/workflows/resume.ts +221 -43
  262. package/src/workflows/retry-poller.ts +39 -24
  263. package/src/workflows/step-input.ts +59 -0
  264. package/src/workflows/task-step-routing.ts +114 -56
  265. package/templates/skills/slack-interaction/content.md +5 -0
  266. package/templates/skills/work-on-task/SKILL.md +1 -1
  267. package/templates/skills/work-on-task/content.md +1 -1
  268. package/dist/cli-9hstj09h.js +0 -2657
  269. package/dist/cli-yw91rnmw.js +0 -13
  270. package/dist/handlers-7gw64dxw.js +0 -39
  271. package/dist/index-bgdyvcnv.js +0 -40
  272. package/dist/index-gabbcdn2.js +0 -43
  273. package/dist/index-tfb26zhy.js +0 -41
  274. package/dist/lead-7e02z839.js +0 -77
  275. package/dist/worker-5snytpbd.js +0 -77
@@ -9,6 +9,7 @@ import {
9
9
  gitlabContextKey,
10
10
  azureDevOpsContextKey,
11
11
  azureDevOpsWorkItemContextKey,
12
+ bitbucketContextKey,
12
13
  linearContextKey,
13
14
  buildJiraContextKey,
14
15
  scheduleContextKey,
@@ -72,6 +73,7 @@ import {
72
73
  hasNonTerminalRerouteDecisionChild2,
73
74
  getAgentCurrentTask2,
74
75
  findTaskByVcs2,
76
+ findActiveTasksByVcs2,
75
77
  readableSessionCondition,
76
78
  getAllTasks2,
77
79
  getPendingChatRelayTasks2,
@@ -334,19 +336,19 @@ import {
334
336
  recordInlineScriptRun2,
335
337
  exports_db,
336
338
  init_db3
337
- } from "./cli-wt0jf9hm.js";
339
+ } from "./cli-q9pzwxvk.js";
338
340
  import {
339
341
  getUserGrant2,
340
342
  init_rbac_roles
341
- } from "./cli-kpw04va0.js";
343
+ } from "./cli-z2dv25mf.js";
342
344
  import {
343
345
  ensurePricingSeeded2,
344
346
  ensureRbacSeeded2,
345
347
  ensureModelProfilesSeeded2
346
- } from "./cli-43x64hv3.js";
348
+ } from "./cli-v2g93k4v.js";
347
349
  import {
348
350
  loadModelsDevCache
349
- } from "./cli-dk44dxec.js";
351
+ } from "./cli-9mm5ade4.js";
350
352
  import {
351
353
  buildCatalogEntries,
352
354
  listModelCatalog,
@@ -356,12 +358,12 @@ import {
356
358
  loadModelsCatalog,
357
359
  requestModelCatalogRefresh2,
358
360
  startPricingRefreshLoop2
359
- } from "./cli-bnes4z6b.js";
361
+ } from "./cli-mz2ygeyq.js";
360
362
  import {
361
363
  ampPinProviderError,
362
364
  ampPinCatalogError,
363
365
  ampModelError
364
- } from "./cli-qfxc84gh.js";
366
+ } from "./cli-jpxsrxcb.js";
365
367
  import {
366
368
  notifyAutomationPreflightFailure,
367
369
  isNeedsSetupFailure,
@@ -370,50 +372,50 @@ import {
370
372
  getAutomationSetupStates,
371
373
  schedulePreflightInput,
372
374
  recordSchedulePreflightFailure,
375
+ BaseExecutor,
376
+ postApprovalCancellationUpdates,
377
+ createApprovalFollowUpTask,
378
+ HumanInTheLoopExecutor,
379
+ resolveWorkflowLlmConfig,
380
+ SYSTEM_ONE_PROVIDER_IDS,
381
+ SystemOneExtractionExecutor,
382
+ SYSTEM_ONE_DECISION_NODE_TYPE,
383
+ SystemOneDecisionConfigSchema,
384
+ SystemOneDecisionExecutor,
373
385
  checkpointStep,
374
386
  checkpointStepFailure,
375
387
  checkpointStepWaiting,
376
- FOREACH_TERMINAL_STEP_STATUSES,
377
- parseSyntheticNodeId,
378
- buildForeachAggregate,
388
+ FAILED_TASK_OUTPUT_PREFIX,
389
+ FOREACH_ITEMS_WAIT_FOR,
379
390
  loadCompletedStepRouting,
380
391
  resolveInputValue,
381
392
  getSecretInputKeys,
382
393
  validateJsonSchema,
383
394
  findJsonSchemaShapeErrors,
384
- getMaxWorkflowStepsPerRun,
385
395
  workflowSaveWarnings,
386
396
  withSaveWarnings,
387
397
  runStepValidation,
388
- shapeApprovalResolution,
389
- FAILED_TASK_OUTPUT_PREFIX,
390
- SubWorkflowExecutor,
391
- WaitExecutor,
392
- failStepAndRunIfWaiting,
393
- checkpointPortStepAndResolveSuccessors,
394
- scheduleTaskStepRetry,
395
- completeTaskStepAndResolveSuccessors,
396
- setupWorkflowResumeListener2,
397
- finalizeOrWait2,
398
- retryFailedRun2,
399
- cancelWorkflowRunRows2,
400
- cancelWorkflowRun2,
401
- resumeWaitState2,
402
- recoverResolvedWaitState2,
403
- resumeFromChildRun2,
404
- initWaitBusSubscriptions2,
405
398
  TriggerSchemaError,
406
399
  startWorkflowExecution2,
407
400
  failRunOnUnreadableReplay,
408
401
  isWorkflowRunActive,
409
402
  holdWorkflowRun,
410
403
  walkGraph,
411
- rehydrateCompletedStepOutputs,
412
404
  findReadyNodes,
413
- buildNodeInterpolationCtx,
414
- interpolateNodeConfig,
415
- scriptBodyInterpolationError
416
- } from "./cli-9hstj09h.js";
405
+ scriptBodyInterpolationError,
406
+ ForeachExecutor,
407
+ rebuildNodeExecutionInput,
408
+ isForeachChildOwned,
409
+ parkAndDriveForeach,
410
+ runForeachDrive,
411
+ stepFailureMode,
412
+ generateEdges,
413
+ resolveValidationPort,
414
+ getSuccessors,
415
+ definitionNodeIds,
416
+ validateDefinition,
417
+ applyDefinitionPatch
418
+ } from "./cli-pyy4c9ch.js";
417
419
  import {
418
420
  require_dist2,
419
421
  publicEndpointSsrfOptions,
@@ -473,14 +475,14 @@ import {
473
475
  deleteApp,
474
476
  typecheckScript,
475
477
  parseSkillContent
476
- } from "./cli-st8aw1m6.js";
478
+ } from "./cli-mq7kg1b1.js";
477
479
  import {
478
480
  buildAuthorizationUrl,
479
481
  onAuthorizationRefreshed,
480
482
  ensureAuthorizationTokenOrThrow,
481
483
  ensureToken,
482
484
  ensureTokenOrThrow
483
- } from "./cli-a92r1127.js";
485
+ } from "./cli-rngde2jv.js";
484
486
  import {
485
487
  detachedProcessGroup,
486
488
  registerProcessGroup,
@@ -510,36 +512,36 @@ import {
510
512
  getSlackApp2,
511
513
  startSlackApp2,
512
514
  stopSlackApp2
513
- } from "./cli-37j04k05.js";
515
+ } from "./cli-e9btqw4y.js";
514
516
  import {
515
517
  slackCode,
516
518
  slackMissingScopeMessage,
517
519
  withAutoJoin,
518
520
  externalChannelToolError2,
519
521
  getChannelBlockReason2
520
- } from "./cli-3a45zcgm.js";
521
- import {
522
- BaseExecutor,
523
- postApprovalCancellationUpdates,
524
- createApprovalFollowUpTask,
525
- HumanInTheLoopExecutor,
526
- resolveWorkflowLlmConfig,
527
- SYSTEM_ONE_PROVIDER_IDS,
528
- SystemOneExtractionExecutor,
529
- SYSTEM_ONE_DECISION_NODE_TYPE,
530
- SystemOneDecisionConfigSchema,
531
- SystemOneDecisionExecutor,
532
- generateEdges,
533
- resolveValidationPort,
534
- getSuccessors,
535
- definitionNodeIds,
536
- validateDefinition,
537
- applyDefinitionPatch
538
- } from "./cli-xpa64rek.js";
522
+ } from "./cli-xc65x52q.js";
539
523
  import {
540
524
  workflowEventBus2,
541
525
  init_event_bus
542
- } from "./cli-wt645v7q.js";
526
+ } from "./cli-dabehxhp.js";
527
+ import {
528
+ shapeApprovalResolution,
529
+ SubWorkflowExecutor,
530
+ WaitExecutor,
531
+ failStepAndRunIfWaiting,
532
+ checkpointPortStepAndResolveSuccessors,
533
+ scheduleTaskStepRetry,
534
+ completeTaskStepAndResolveSuccessors,
535
+ setupWorkflowResumeListener2,
536
+ finalizeOrWait2,
537
+ retryFailedRun2,
538
+ cancelWorkflowRunRows2,
539
+ cancelWorkflowRun2,
540
+ resumeWaitState2,
541
+ recoverResolvedWaitState2,
542
+ resumeFromChildRun2,
543
+ initWaitBusSubscriptions2
544
+ } from "./cli-nj12tn2c.js";
543
545
  import {
544
546
  duplicateGuardedQueryKey,
545
547
  parseQueryParams,
@@ -566,7 +568,7 @@ import {
566
568
  isPublicRoute,
567
569
  findRoute,
568
570
  route
569
- } from "./cli-018r4jq6.js";
571
+ } from "./cli-y3zyaee5.js";
570
572
  import {
571
573
  isMultiRuntimeEnabled
572
574
  } from "./cli-e8xyjvfc.js";
@@ -580,7 +582,7 @@ import {
580
582
  import {
581
583
  getRuntimePool2,
582
584
  init_db
583
- } from "./cli-j99azg3g.js";
585
+ } from "./cli-1dp1zj04.js";
584
586
  import {
585
587
  getMemoryRaterNames,
586
588
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -591,7 +593,7 @@ import {
591
593
  COMPOSIO_HTTP_METHODS,
592
594
  executeComposioRequest,
593
595
  composioArgsFromParts
594
- } from "./cli-smvcw9z5.js";
596
+ } from "./cli-pasyvjmm.js";
595
597
  import {
596
598
  require_fast_deep_equal
597
599
  } from "./cli-bhp11egn.js";
@@ -605,7 +607,7 @@ import {
605
607
  import {
606
608
  canProvisionKind,
607
609
  init_runtime_providers
608
- } from "./cli-625tb7aq.js";
610
+ } from "./cli-p859hcc8.js";
609
611
  import {
610
612
  findUserById,
611
613
  findUserByExternalId,
@@ -621,7 +623,7 @@ import {
621
623
  resolveSessionToken,
622
624
  fingerprintApiKey,
623
625
  init_users
624
- } from "./cli-1f3qzw6y.js";
626
+ } from "./cli-gwcf52gz.js";
625
627
  import {
626
628
  isRbacEnabled,
627
629
  decideAdmission,
@@ -690,7 +692,7 @@ import {
690
692
  KvNamespaceSchema,
691
693
  KvKeySchema,
692
694
  init_types
693
- } from "./cli-eww120g8.js";
695
+ } from "./cli-rh5smt8t.js";
694
696
  import {
695
697
  generateDefaultClaudeMd2,
696
698
  generateDefaultSoulMd2,
@@ -699,7 +701,7 @@ import {
699
701
  taskAttachmentFetchCommand,
700
702
  taskAttachmentDisplayUrl,
701
703
  init_task_attachment_links
702
- } from "./cli-74c1wpm0.js";
704
+ } from "./cli-gpv60278.js";
703
705
  import {
704
706
  getSlackConfiguration,
705
707
  init_config
@@ -711,7 +713,6 @@ import {
711
713
  import {
712
714
  findInterpolationTokens,
713
715
  interpolate,
714
- deepInterpolate,
715
716
  init_template,
716
717
  registerTemplate,
717
718
  getTemplateDefinition,
@@ -737,7 +738,6 @@ import {
737
738
  _null,
738
739
  any,
739
740
  unknown,
740
- never,
741
741
  array2,
742
742
  object2,
743
743
  looseObject,
@@ -761,7 +761,7 @@ import {
761
761
  import {
762
762
  init_package,
763
763
  package_default
764
- } from "./cli-94gwyg7m.js";
764
+ } from "./cli-22rmcjkg.js";
765
765
  import {
766
766
  realtimeBus,
767
767
  init_bus
@@ -795,7 +795,7 @@ import {
795
795
  registerVolatileSecret,
796
796
  registerSensitiveKeyName,
797
797
  init_secret_scrubber
798
- } from "./cli-xf234ws8.js";
798
+ } from "./cli-n4c8e3s5.js";
799
799
  import {
800
800
  isAlias,
801
801
  parseAlias,
@@ -20137,6 +20137,7 @@ async function recoverIncompleteRuns(registry) {
20137
20137
  console.error(`[workflows] Failed to resume sub-workflow step ${parentStepId}:`, err);
20138
20138
  }
20139
20139
  }
20140
+ recovered += await recoverForeachFanouts(registry);
20140
20141
  if (recovered > 0) {
20141
20142
  console.log(`[workflows] Recovered ${recovered} incomplete run(s)`);
20142
20143
  }
@@ -20230,10 +20231,10 @@ async function recoverWaitingRuns(registry) {
20230
20231
  if (retry !== "not-eligible")
20231
20232
  continue;
20232
20233
  }
20233
- if (!taskCompleted && (workflow.definition.onNodeFailure ?? "fail") === "fail") {
20234
+ if (!taskCompleted && stepFailureMode(workflow.definition, stuck.nodeId) === "fail") {
20234
20235
  const reason = stuck.taskStatus === "failed" ? "Task failed (recovered)" : "Task cancelled (recovered)";
20235
- const claimed = await failStepAndRunIfWaiting(stuck.stepId, stuck.runId, reason, stuck.taskId);
20236
- if (!claimed)
20236
+ const failed = await failStepAndRunIfWaiting(workflow.definition, stuck.stepId, stuck.runId, reason, stuck.taskId, { registry });
20237
+ if (!failed.claimed)
20237
20238
  continue;
20238
20239
  recovered++;
20239
20240
  continue;
@@ -20247,7 +20248,7 @@ async function recoverWaitingRuns(registry) {
20247
20248
  const step = await getWorkflowRunStep2(stuck.stepId);
20248
20249
  if (!step)
20249
20250
  continue;
20250
- const routing = await completeTaskStepAndResolveSuccessors(workflow.definition, stuck.runId, step, stepOutput, ctx, taskCompleted ? undefined : reason, stuck.taskId);
20251
+ const routing = await completeTaskStepAndResolveSuccessors(workflow.definition, stuck.runId, step, stepOutput, ctx, taskCompleted ? undefined : reason, stuck.taskId, registry);
20251
20252
  if (!routing.claimed)
20252
20253
  continue;
20253
20254
  if (routing.foreachChild && !routing.joined) {
@@ -20302,7 +20303,7 @@ async function recoverApprovalWaitingRuns(registry) {
20302
20303
  status: approvalStatus,
20303
20304
  responses: approval?.responses ?? null
20304
20305
  });
20305
- return await checkpointPortStepAndResolveSuccessors(workflow.definition, stuck.runId, stuck.stepId, stuck.nodeId, stepOutput, nextPort, ctx);
20306
+ return await checkpointPortStepAndResolveSuccessors(workflow.definition, stuck.runId, stuck.stepId, stuck.nodeId, stepOutput, nextPort, ctx, registry);
20306
20307
  });
20307
20308
  if (!routing?.claimed)
20308
20309
  continue;
@@ -20341,6 +20342,42 @@ async function recoverWaitStates(registry) {
20341
20342
  }
20342
20343
  return recovered;
20343
20344
  }
20345
+ async function recoverForeachFanouts(registry) {
20346
+ const rows = await getDbClient2().query(`SELECT s.runId AS runId, r.workflowId AS workflowId, s.id AS stepId, s.nodeId AS nodeId, s.status AS status
20347
+ FROM workflow_run_steps s
20348
+ JOIN workflow_runs r ON r.id = s.runId
20349
+ WHERE r.status IN ('running', 'waiting')
20350
+ AND s.status IN ('pending', 'running')
20351
+ AND instr(s.nodeId, '#') > 1`);
20352
+ const fanouts = new Map;
20353
+ for (const row of rows) {
20354
+ if (row.status === "running" && isForeachChildOwned(row.stepId))
20355
+ continue;
20356
+ const parentNodeId = row.nodeId.slice(0, row.nodeId.indexOf("#"));
20357
+ fanouts.set(`${row.runId}\x00${parentNodeId}`, {
20358
+ runId: row.runId,
20359
+ workflowId: row.workflowId,
20360
+ parentNodeId
20361
+ });
20362
+ }
20363
+ let recovered = 0;
20364
+ for (const fanout of fanouts.values()) {
20365
+ try {
20366
+ const workflow = await getWorkflow2(fanout.workflowId);
20367
+ const parent = workflow?.definition.nodes.find((node) => node.id === fanout.parentNodeId);
20368
+ if (parent?.type !== "foreach")
20369
+ continue;
20370
+ const drive = await runForeachDrive(fanout.runId, fanout.parentNodeId, registry);
20371
+ if (drive.claimed > 0)
20372
+ recovered++;
20373
+ } catch (err) {
20374
+ if (await failRunOnUnreadableReplay(fanout.runId, err))
20375
+ continue;
20376
+ console.error(`[workflows] Failed to re-drive foreach ${fanout.parentNodeId} of run ${fanout.runId}:`, err);
20377
+ }
20378
+ }
20379
+ return recovered;
20380
+ }
20344
20381
  async function getRunIdsByStatus(status) {
20345
20382
  const rows = await getDbClient2().query("SELECT id FROM workflow_runs WHERE status = ?", [status]);
20346
20383
  return rows.map((r) => r.id);
@@ -20370,17 +20407,16 @@ function startRetryPoller(registry, intervalMs = 5000) {
20370
20407
  release = holdWorkflowRun(run.id);
20371
20408
  if (!await claimRetry(run.id, step.id))
20372
20409
  continue;
20373
- const ctx = run.context ?? {};
20374
- if (!("run" in ctx))
20375
- ctx.run = { id: run.id };
20376
- await rehydrateCompletedStepOutputs(workflow.definition, run.id, ctx, registry);
20377
- const inputCtx = buildNodeInterpolationCtx(node, ctx);
20378
- const { value: interpolatedValue, scriptBodyUnresolved } = interpolateNodeConfig(node, inputCtx);
20410
+ const {
20411
+ ctx,
20412
+ inputCtx,
20413
+ config: interpolatedConfig,
20414
+ scriptBodyUnresolved
20415
+ } = await rebuildNodeExecutionInput(workflow.definition, run, node, registry);
20379
20416
  if (scriptBodyUnresolved && scriptBodyUnresolved.length > 0) {
20380
20417
  await checkpointStepFailure(run.id, step.id, scriptBodyInterpolationError(node.id, scriptBodyUnresolved), step.retryCount);
20381
20418
  continue;
20382
20419
  }
20383
- const interpolatedConfig = interpolatedValue;
20384
20420
  const executor = registry.get(node.type);
20385
20421
  const meta = {
20386
20422
  runId: run.id,
@@ -20400,6 +20436,21 @@ function startRetryPoller(registry, intervalMs = 5000) {
20400
20436
  if (result.status === "failed") {
20401
20437
  const retryPolicy = node.retry || executor.retryPolicy;
20402
20438
  await checkpointStepFailure(run.id, step.id, result.error || "Retry failed", step.retryCount, retryPolicy);
20439
+ } else if ("async" in result && result.async && result.waitFor === FOREACH_ITEMS_WAIT_FOR) {
20440
+ const drive = await parkAndDriveForeach({
20441
+ runId: run.id,
20442
+ stepId: step.id,
20443
+ parentNodeId: node.id,
20444
+ ctx,
20445
+ registry
20446
+ });
20447
+ if (!drive.joined)
20448
+ continue;
20449
+ if (drive.successors.length > 0) {
20450
+ await walkGraph(workflow.definition, run.id, ctx, drive.successors, registry, workflow.id);
20451
+ } else {
20452
+ await completeRunIfSettled(run.id, ctx);
20453
+ }
20403
20454
  } else if ("async" in result && result.async) {
20404
20455
  const waiting = await checkpointStepWaiting(run.id, step.id, ctx);
20405
20456
  if (!waiting)
@@ -21025,154 +21076,6 @@ class CodeMatchExecutor extends BaseExecutor {
21025
21076
  }
21026
21077
  }
21027
21078
 
21028
- // src/workflows/executors/foreach.ts
21029
- init_zod();
21030
- init_template();
21031
- var ForeachBodySchema = object2({
21032
- type: literal2("agent-task"),
21033
- config: record2(string2(), unknown())
21034
- });
21035
- var ForeachConfigSchema = object2({
21036
- over: array2(record2(string2(), unknown())),
21037
- itemKey: string2().min(1),
21038
- body: ForeachBodySchema,
21039
- concurrency: never().optional()
21040
- });
21041
- var ForeachResultSchema = object2({
21042
- itemKey: string2(),
21043
- status: _enum2(["completed", "failed", "cancelled", "skipped"]),
21044
- output: unknown().optional()
21045
- });
21046
- var ForeachOutputSchema = object2({
21047
- results: array2(ForeachResultSchema),
21048
- okCount: number2().int().nonnegative(),
21049
- failedCount: number2().int().nonnegative()
21050
- });
21051
-
21052
- class ForeachExecutor extends BaseExecutor {
21053
- type = "foreach";
21054
- mode = "async";
21055
- configSchema = ForeachConfigSchema;
21056
- outputSchema = ForeachOutputSchema;
21057
- async execute(config, context, meta) {
21058
- if (config.over.length === 0) {
21059
- return {
21060
- status: "success",
21061
- output: { results: [], okCount: 0, failedCount: 0 }
21062
- };
21063
- }
21064
- const items = config.over.map((item, index) => {
21065
- const rawItemKey = item[config.itemKey];
21066
- if (typeof rawItemKey !== "string" || rawItemKey.length === 0) {
21067
- throw new Error(`foreach item at index ${index} is missing non-empty string itemKey property "${config.itemKey}"`);
21068
- }
21069
- return { item, index, itemKey: rawItemKey };
21070
- });
21071
- const seenItemKeys = new Set;
21072
- for (const { itemKey } of items) {
21073
- if (seenItemKeys.has(itemKey)) {
21074
- throw new Error(`foreach itemKey "${itemKey}" is duplicated`);
21075
- }
21076
- seenItemKeys.add(itemKey);
21077
- }
21078
- const agentTaskExecutor = new AgentTaskExecutor(this.deps);
21079
- const runSteps = await this.deps.db.getWorkflowRunStepsByRunId(meta.runId);
21080
- const childStepsByNodeId = new Map(runSteps.filter((step) => parseSyntheticNodeId(step.nodeId)?.parentNodeId === meta.nodeId).map((step) => [step.nodeId, step]));
21081
- const childCountToCreate = items.filter(({ itemKey }) => !childStepsByNodeId.has(`${meta.nodeId}#${itemKey}`)).length;
21082
- const maxSteps = getMaxWorkflowStepsPerRun();
21083
- const workflow = await this.deps.db.getWorkflow(meta.workflowId);
21084
- const hasSuccessors = workflow ? getSuccessors(workflow.definition, meta.nodeId).length > 0 : true;
21085
- const totalSteps = runSteps.length + childCountToCreate;
21086
- const capBreached = hasSuccessors ? totalSteps >= maxSteps : totalSteps > maxSteps;
21087
- if (childCountToCreate > 0 && capBreached) {
21088
- return {
21089
- status: "failed",
21090
- error: `foreach would reach ${maxSteps} total steps (WORKFLOW_MAX_STEPS_PER_RUN): ${runSteps.length} existing + ${childCountToCreate} children${hasSuccessors ? " leaves no room for the post-join walk" : " exceeds the per-run cap"}`
21091
- };
21092
- }
21093
- for (const { index, itemKey } of items) {
21094
- const childNodeId = `${meta.nodeId}#${itemKey}`;
21095
- if (childStepsByNodeId.has(childNodeId))
21096
- continue;
21097
- const childStepId = crypto.randomUUID();
21098
- const childStep = await this.deps.db.createWorkflowRunStep({
21099
- id: childStepId,
21100
- runId: meta.runId,
21101
- nodeId: childNodeId,
21102
- nodeType: "agent-task",
21103
- input: { itemKey, index }
21104
- });
21105
- await this.deps.db.updateWorkflowRunStep(childStepId, {
21106
- idempotencyKey: `${meta.runId}:${childNodeId}:0`
21107
- });
21108
- childStepsByNodeId.set(childNodeId, childStep);
21109
- }
21110
- for (const { item, index, itemKey } of items) {
21111
- const childNodeId = `${meta.nodeId}#${itemKey}`;
21112
- const childStep = childStepsByNodeId.get(childNodeId);
21113
- if (FOREACH_TERMINAL_STEP_STATUSES.has(childStep.status))
21114
- continue;
21115
- const bodyCtx = { ...meta.inputCtx ?? context, item, index };
21116
- const childInterpolation = deepInterpolate(config.body.config, bodyCtx);
21117
- if (childInterpolation.unresolved.length > 0) {
21118
- console.warn(`[workflow] Step ${childNodeId}: unresolved interpolation tokens: ${childInterpolation.unresolved.join(", ")}`);
21119
- await this.deps.db.updateWorkflowRunStep(childStep.id, {
21120
- diagnostics: JSON.stringify({ unresolvedTokens: childInterpolation.unresolved })
21121
- });
21122
- }
21123
- const linkedTask = await this.deps.db.getTaskByWorkflowRunStepId(childStep.id);
21124
- if (linkedTask?.status === "failed" || linkedTask?.status === "cancelled") {
21125
- await this.deps.db.detachTaskFromWorkflowRunStep(linkedTask.id);
21126
- }
21127
- const childResult = await agentTaskExecutor.run({
21128
- config: childInterpolation.value,
21129
- context,
21130
- meta: {
21131
- ...meta,
21132
- stepId: childStep.id,
21133
- nodeId: childNodeId
21134
- }
21135
- });
21136
- if (childResult.status !== "success") {
21137
- throw new Error(childResult.error ?? `foreach child "${itemKey}" failed to start`);
21138
- }
21139
- if ("async" in childResult) {
21140
- await this.deps.db.updateWorkflowRunStep(childStep.id, { status: "waiting" });
21141
- } else {
21142
- await this.deps.db.updateWorkflowRunStep(childStep.id, {
21143
- status: "completed",
21144
- output: normalizeExistingTaskOutput(childResult.output),
21145
- finishedAt: new Date().toISOString()
21146
- });
21147
- }
21148
- }
21149
- const childSteps = (await this.deps.db.getWorkflowRunStepsByRunId(meta.runId)).filter((step) => parseSyntheticNodeId(step.nodeId)?.parentNodeId === meta.nodeId);
21150
- if (childSteps.every((step) => FOREACH_TERMINAL_STEP_STATUSES.has(step.status))) {
21151
- return { status: "success", output: buildForeachAggregate(childSteps) };
21152
- }
21153
- return {
21154
- status: "success",
21155
- async: true,
21156
- waitFor: "task.completed",
21157
- correlationId: meta.stepId
21158
- };
21159
- }
21160
- }
21161
- function normalizeExistingTaskOutput(output) {
21162
- if (typeof output !== "object" || output === null)
21163
- return output;
21164
- const record = output;
21165
- if (typeof record.taskOutput !== "string")
21166
- return output;
21167
- try {
21168
- const parsed = JSON.parse(record.taskOutput);
21169
- if (typeof parsed === "object" && parsed !== null) {
21170
- return { ...record, taskOutput: parsed };
21171
- }
21172
- } catch {}
21173
- return output;
21174
- }
21175
-
21176
21079
  // src/workflows/executors/notify.ts
21177
21080
  init_zod();
21178
21081
  init_secret_scrubber();
@@ -21216,7 +21119,7 @@ class NotifyExecutor extends BaseExecutor {
21216
21119
  }
21217
21120
  }
21218
21121
  case "slack": {
21219
- const { getSlackApp } = await import("./app-353vre8g.js");
21122
+ const { getSlackApp } = await import("./app-nndcvftq.js");
21220
21123
  const app = getSlackApp();
21221
21124
  if (!app) {
21222
21125
  return {
@@ -24579,7 +24482,7 @@ function setPreloadedTools(server, names) {
24579
24482
  async function applyPreToolCall(name, args, requestInfo, inputSchema) {
24580
24483
  if (requestInfo.callOrigin !== "mcp")
24581
24484
  return { args };
24582
- const dispatcher = await import("./dispatcher-c155xz0p.js");
24485
+ const dispatcher = await import("./dispatcher-606ydx5v.js");
24583
24486
  const result = await dispatcher.dispatchPre("pre.tool.call", { tool: name, args, requestInfo }, inputSchema ? {
24584
24487
  validateModify: async (data) => {
24585
24488
  const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
@@ -25789,7 +25692,8 @@ var onChatMessageSent = chatMessageBridge("chat.message.sent", "outbound");
25789
25692
  var VCS_PROVIDERS = new Set([
25790
25693
  "github",
25791
25694
  "gitlab",
25792
- "azure-devops"
25695
+ "azure-devops",
25696
+ "bitbucket"
25793
25697
  ]);
25794
25698
  var VCS_KINDS = new Set([
25795
25699
  "pull_request",
@@ -28080,7 +27984,7 @@ async function handlePullRequestCommented(event) {
28080
27984
  return { created: false };
28081
27985
  }
28082
27986
  const requestedByUserId = await resolveAzureDevOpsSender(comment.author, "pull_request_comment", comment.content);
28083
- const existingTask = await findTaskByVcs2(repo, pr.pullRequestId);
27987
+ const existingTask = await findTaskByVcs2(repo, pr.pullRequestId, "azure-devops");
28084
27988
  const existingTaskNote = existingTask ? `
28085
27989
 
28086
27990
  _Note: There's an active task (${existingTask.id}) for this PR #${pr.pullRequestId}._` : "";
@@ -29194,6 +29098,456 @@ async function syncTelemetryEnabled(via) {
29194
29098
  track({ event: "telemetry.enabled", properties: { via } });
29195
29099
  return true;
29196
29100
  }
29101
+
29102
+ // src/bitbucket/api.ts
29103
+ init_secret_scrubber();
29104
+
29105
+ // src/bitbucket/auth.ts
29106
+ init_env_flag();
29107
+ var initialized4 = false;
29108
+ var webhookSecret4 = null;
29109
+ var apiToken2 = null;
29110
+ function isBitbucketEnabled() {
29111
+ return !!process.env.BITBUCKET_WEBHOOK_SECRET && !isEnvFlagEnabled("BITBUCKET_DISABLE", false);
29112
+ }
29113
+ function initBitbucket() {
29114
+ if (initialized4)
29115
+ return;
29116
+ if (!isBitbucketEnabled()) {
29117
+ console.log("[Bitbucket] Integration disabled (BITBUCKET_WEBHOOK_SECRET not set)");
29118
+ return;
29119
+ }
29120
+ webhookSecret4 = process.env.BITBUCKET_WEBHOOK_SECRET;
29121
+ apiToken2 = process.env.BITBUCKET_TOKEN ?? null;
29122
+ initialized4 = true;
29123
+ console.log(`[Bitbucket] Integration initialized (API token: ${apiToken2 ? "set" : "not set"})`);
29124
+ }
29125
+ function verifyBitbucketWebhook(rawBody, signatureHeader) {
29126
+ if (!webhookSecret4)
29127
+ return false;
29128
+ if (!signatureHeader?.startsWith("sha256="))
29129
+ return false;
29130
+ return verifyHmacSignature(webhookSecret4, rawBody, signatureHeader);
29131
+ }
29132
+ function getBitbucketToken() {
29133
+ return apiToken2;
29134
+ }
29135
+ function getBitbucketBotName() {
29136
+ return process.env.BITBUCKET_BOT_NAME || "agent-swarm-bot";
29137
+ }
29138
+ function resetBitbucket() {
29139
+ initialized4 = false;
29140
+ webhookSecret4 = null;
29141
+ apiToken2 = null;
29142
+ }
29143
+
29144
+ // src/bitbucket/api.ts
29145
+ var BITBUCKET_API = "https://api.bitbucket.org/2.0";
29146
+ function headers3() {
29147
+ const token = getBitbucketToken();
29148
+ if (!token)
29149
+ throw new Error("[Bitbucket] No API token configured");
29150
+ return {
29151
+ Authorization: `Bearer ${token}`,
29152
+ "Content-Type": "application/json",
29153
+ Accept: "application/json"
29154
+ };
29155
+ }
29156
+ var cachedBotAccountId = null;
29157
+ async function resolveBitbucketBotAccountId() {
29158
+ const fromEnv = process.env.BITBUCKET_BOT_ACCOUNT_ID?.trim();
29159
+ if (fromEnv)
29160
+ return fromEnv;
29161
+ if (cachedBotAccountId)
29162
+ return cachedBotAccountId;
29163
+ if (!getBitbucketToken())
29164
+ return null;
29165
+ try {
29166
+ const resp = await fetch(`${BITBUCKET_API}/user`, { headers: headers3(), redirect: "error" });
29167
+ if (!resp.ok) {
29168
+ console.error(`[Bitbucket] GET /user returned ${resp.status}`);
29169
+ return null;
29170
+ }
29171
+ const data = await resp.json();
29172
+ cachedBotAccountId = data.account_id?.trim() || null;
29173
+ return cachedBotAccountId;
29174
+ } catch (err) {
29175
+ console.error(`[Bitbucket] Failed to resolve bot identity: ${scrubSecrets(String(err))}`);
29176
+ return null;
29177
+ }
29178
+ }
29179
+ function resetBitbucketBotCache() {
29180
+ cachedBotAccountId = null;
29181
+ }
29182
+ // src/bitbucket/handlers.ts
29183
+ init_db3();
29184
+ init_users();
29185
+ init_resolver();
29186
+ init_context_key();
29187
+
29188
+ // src/bitbucket/templates.ts
29189
+ init_registry();
29190
+ registerTemplate({
29191
+ eventType: "common.delegation_instruction.bitbucket",
29192
+ header: "",
29193
+ defaultBody: "\n\n**Delegation instruction:** As the lead agent, analyze this and decide whether to handle it yourself or delegate to a worker agent. Use `send-task` to delegate with clear instructions.",
29194
+ variables: [],
29195
+ category: "common"
29196
+ });
29197
+ registerTemplate({
29198
+ eventType: "common.command_suggestions.bitbucket_pr",
29199
+ header: "",
29200
+ defaultBody: 'Workers have `git` authenticated for bitbucket.org and `BITBUCKET_TOKEN` in env; there is no Bitbucket CLI, so use curl against `https://api.bitbucket.org/2.0/repositories/{{repo}}` with `-H "Authorization: Bearer $BITBUCKET_TOKEN"`. Inspect the PR with `GET .../pullrequests/{{pr_id}}` and its diff with `GET .../pullrequests/{{pr_id}}/diff`. Reply with `POST .../pullrequests/{{pr_id}}/comments` and JSON body `{"content":{"raw":"<reply>"}}`. Find a PR by branch with `GET .../pullrequests?q=source.branch.name="<branch>"`. Open a PR with `POST .../pullrequests` and JSON body `{"title":"<title>","source":{"branch":{"name":"<branch>"}},"destination":{"branch":{"name":"<base>"}}}`.',
29201
+ variables: [
29202
+ { name: "repo", description: "Repository full name (<workspace>/<repo_slug>)" },
29203
+ { name: "pr_id", description: "Pull request ID" }
29204
+ ],
29205
+ category: "common"
29206
+ });
29207
+ var SHARED_VARIABLES2 = [
29208
+ { name: "pr_id", description: "Pull request ID" },
29209
+ { name: "pr_title", description: "Pull request title" },
29210
+ { name: "repo", description: "Repository full name (<workspace>/<repo_slug>)" },
29211
+ { name: "pr_url", description: "Pull request web URL" }
29212
+ ];
29213
+ var PR_BRANCH_VARIABLES = [
29214
+ { name: "source_branch", description: "Source branch name" },
29215
+ { name: "target_branch", description: "Target branch name" },
29216
+ { name: "context_section", description: "Context section with description or empty string" }
29217
+ ];
29218
+ registerTemplate({
29219
+ eventType: "bitbucket.pull_request.opened",
29220
+ header: "[Bitbucket PR #{{pr_id}}] {{pr_title}}",
29221
+ defaultBody: `Repo: {{repo}}
29222
+ Author: {{username}}
29223
+ Branch: {{source_branch}} → {{target_branch}}
29224
+ URL: {{pr_url}}
29225
+
29226
+ {{context_section}}{{@template[common.command_suggestions.bitbucket_pr]}}{{@template[common.delegation_instruction.bitbucket]}}`,
29227
+ variables: [
29228
+ ...SHARED_VARIABLES2,
29229
+ {
29230
+ name: "username",
29231
+ description: "Author identity — resolved canonical name (e.g. 'Luis (bitbucket:557058:…)') or the UNKNOWN sentinel"
29232
+ },
29233
+ ...PR_BRANCH_VARIABLES
29234
+ ],
29235
+ category: "event"
29236
+ });
29237
+ registerTemplate({
29238
+ eventType: "bitbucket.pull_request.review_requested",
29239
+ header: "[Bitbucket PR #{{pr_id}}] Review requested: {{pr_title}}",
29240
+ defaultBody: `Repo: {{repo}}
29241
+ Author: {{username}}
29242
+ Branch: {{source_branch}} → {{target_branch}}
29243
+ URL: {{pr_url}}
29244
+
29245
+ You were added as a reviewer on this pull request.
29246
+
29247
+ {{context_section}}{{@template[common.command_suggestions.bitbucket_pr]}}{{@template[common.delegation_instruction.bitbucket]}}`,
29248
+ variables: [
29249
+ ...SHARED_VARIABLES2,
29250
+ {
29251
+ name: "username",
29252
+ description: "Author identity — resolved canonical name (e.g. 'Luis (bitbucket:557058:…)') or the UNKNOWN sentinel"
29253
+ },
29254
+ ...PR_BRANCH_VARIABLES
29255
+ ],
29256
+ category: "event"
29257
+ });
29258
+ registerTemplate({
29259
+ eventType: "bitbucket.comment.mentioned",
29260
+ header: "[Bitbucket Comment on PR #{{pr_id}}] {{username}} mentioned bot",
29261
+ defaultBody: `Repo: {{repo}}
29262
+ PR: {{pr_title}}
29263
+ URL: {{pr_url}}
29264
+ {{location_section}}
29265
+ Comment:
29266
+ {{context}}{{existing_task_note}}
29267
+
29268
+ {{@template[common.command_suggestions.bitbucket_pr]}}{{@template[common.delegation_instruction.bitbucket]}}`,
29269
+ variables: [
29270
+ ...SHARED_VARIABLES2,
29271
+ {
29272
+ name: "username",
29273
+ description: "Comment author identity — resolved canonical name (e.g. 'Luis (bitbucket:557058:…)') or the UNKNOWN sentinel"
29274
+ },
29275
+ {
29276
+ name: "location_section",
29277
+ description: "`File: <path>:<line>` line for inline comments, or empty string"
29278
+ },
29279
+ { name: "context", description: "Extracted mention context from comment" },
29280
+ {
29281
+ name: "existing_task_note",
29282
+ description: "Note about existing active task, or empty string"
29283
+ }
29284
+ ],
29285
+ category: "event"
29286
+ });
29287
+
29288
+ // src/bitbucket/handlers.ts
29289
+ var DEDUP_TTL_MS2 = 60000;
29290
+ var processedEvents3 = new Map;
29291
+ var processedDeliveries = new Map;
29292
+ function sweep(cache, now) {
29293
+ for (const [k, ts] of cache) {
29294
+ if (now - ts > DEDUP_TTL_MS2)
29295
+ cache.delete(k);
29296
+ }
29297
+ }
29298
+ function isDuplicate3(key) {
29299
+ const now = Date.now();
29300
+ sweep(processedEvents3, now);
29301
+ if (processedEvents3.has(key))
29302
+ return true;
29303
+ processedEvents3.set(key, now);
29304
+ return false;
29305
+ }
29306
+ async function withDedupReservation(key, fn) {
29307
+ if (isDuplicate3(key))
29308
+ return null;
29309
+ try {
29310
+ return await fn();
29311
+ } catch (err) {
29312
+ processedEvents3.delete(key);
29313
+ throw err;
29314
+ }
29315
+ }
29316
+ function isDuplicateDelivery(requestUuid) {
29317
+ if (!requestUuid)
29318
+ return false;
29319
+ sweep(processedDeliveries, Date.now());
29320
+ return processedDeliveries.has(requestUuid);
29321
+ }
29322
+ function markDeliveryProcessed(requestUuid) {
29323
+ if (requestUuid)
29324
+ processedDeliveries.set(requestUuid, Date.now());
29325
+ }
29326
+ function escapeRegExp2(value) {
29327
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
29328
+ }
29329
+ function mentionPatterns2(botAccountId) {
29330
+ const patterns = [new RegExp(`@${escapeRegExp2(getBitbucketBotName())}(?![\\w-])`, "gi")];
29331
+ if (botAccountId)
29332
+ patterns.push(new RegExp(`@\\{${escapeRegExp2(botAccountId)}\\}`, "gi"));
29333
+ return patterns;
29334
+ }
29335
+ function detectMention2(text, botAccountId) {
29336
+ if (!text)
29337
+ return false;
29338
+ return mentionPatterns2(botAccountId).some((re) => {
29339
+ re.lastIndex = 0;
29340
+ return re.test(text);
29341
+ });
29342
+ }
29343
+ function extractMentionContext2(text, botAccountId) {
29344
+ return mentionPatterns2(botAccountId).reduce((acc, re) => acc.replace(re, ""), text).trim();
29345
+ }
29346
+ function isBot2(account, botAccountId) {
29347
+ return !!botAccountId && account?.account_id === botAccountId;
29348
+ }
29349
+ function pullRequestWebUrl2(repo, pr) {
29350
+ return pr.links?.html?.href ?? `https://bitbucket.org/${repo}/pull-requests/${pr.id}`;
29351
+ }
29352
+ function contextKeyOf(event) {
29353
+ return bitbucketContextKey({
29354
+ repoUuid: event.repository.uuid,
29355
+ pullRequestId: event.pullrequest.id
29356
+ });
29357
+ }
29358
+ function pullRequestEventOf(body) {
29359
+ const event = body;
29360
+ const pr = event?.pullrequest;
29361
+ const repo = event?.repository;
29362
+ if (typeof pr?.id !== "number" || typeof pr.title !== "string" || typeof repo?.uuid !== "string" || typeof repo.full_name !== "string" || !event?.actor) {
29363
+ return null;
29364
+ }
29365
+ return event;
29366
+ }
29367
+ function pullRequestCommentEventOf(body) {
29368
+ const event = pullRequestEventOf(body);
29369
+ const comment = event?.comment;
29370
+ if (!event || typeof comment?.id !== "number" || typeof comment.content?.raw !== "string") {
29371
+ return null;
29372
+ }
29373
+ return event;
29374
+ }
29375
+ function warnMalformed2(eventKey) {
29376
+ console.warn(`[Bitbucket] Ignoring ${eventKey} event: required payload fields are missing`);
29377
+ }
29378
+ async function findLeadAgent3() {
29379
+ const agents = await getAllAgents2();
29380
+ return agents.find((a) => a.role === "lead" && a.status === "idle") ?? agents.find((a) => a.role === "lead") ?? null;
29381
+ }
29382
+ var UNMAPPED_NAMESPACE2 = "integration:unmapped:bitbucket";
29383
+ var UNMAPPED_TTL_MS2 = 30 * 24 * 60 * 60 * 1000;
29384
+ function externalIdOf2(account) {
29385
+ return account?.account_id?.trim() || account?.uuid?.trim() || null;
29386
+ }
29387
+ async function resolveBitbucketSender(account, sampleEventType, sampleContext) {
29388
+ const externalId = externalIdOf2(account);
29389
+ if (!externalId)
29390
+ return;
29391
+ const existing = await findUserByExternalId("bitbucket", externalId);
29392
+ if (existing)
29393
+ return existing.id;
29394
+ await upsertKv2({
29395
+ namespace: UNMAPPED_NAMESPACE2,
29396
+ key: `${externalId}:meta`,
29397
+ value: {
29398
+ lastSeenAt: new Date().toISOString(),
29399
+ displayName: account?.display_name,
29400
+ sampleEventType,
29401
+ sampleContext: sampleContext.slice(0, 100)
29402
+ },
29403
+ valueType: "json",
29404
+ expiresAt: Date.now() + UNMAPPED_TTL_MS2
29405
+ });
29406
+ await incrKv2(UNMAPPED_NAMESPACE2, `${externalId}:count`, 1);
29407
+ return;
29408
+ }
29409
+ async function renderBitbucketIdentity(account) {
29410
+ return renderIdentity(await resolveIdentity("bitbucket", externalIdOf2(account) ?? ""));
29411
+ }
29412
+ async function createBitbucketTask(text, event, fields) {
29413
+ const { pullrequest: pr, repository } = event;
29414
+ const lead = await findLeadAgent3();
29415
+ const task = await createTaskWithSiblingAwareness(text, {
29416
+ agentId: lead?.id ?? null,
29417
+ routingReason: lead ? "skill" : undefined,
29418
+ routingSource: lead ? "engine_default" : undefined,
29419
+ source: "bitbucket",
29420
+ vcsProvider: "bitbucket",
29421
+ taskType: fields.taskType,
29422
+ vcsRepo: repository.full_name,
29423
+ vcsEventType: fields.vcsEventType,
29424
+ vcsNumber: pr.id,
29425
+ vcsCommentId: fields.vcsCommentId,
29426
+ vcsAuthor: externalIdOf2(fields.author) ?? undefined,
29427
+ requestedByUserId: fields.requestedByUserId,
29428
+ vcsUrl: pullRequestWebUrl2(repository.full_name, pr),
29429
+ parentTaskId: fields.parentTaskId,
29430
+ contextKey: contextKeyOf(event)
29431
+ }, { origin: "webhook" });
29432
+ return { created: true, taskId: task.id };
29433
+ }
29434
+ async function handlePullRequestCreated2(body) {
29435
+ const event = pullRequestEventOf(body);
29436
+ if (!event) {
29437
+ warnMalformed2("pullrequest:created");
29438
+ return { created: false };
29439
+ }
29440
+ const { pullrequest: pr, repository } = event;
29441
+ const repo = repository.full_name;
29442
+ const author = pr.author ?? event.actor;
29443
+ console.log(`[Bitbucket] PR #${pr.id} created by ${author.display_name} in ${repo}`);
29444
+ const botAccountId = await resolveBitbucketBotAccountId();
29445
+ if (isBot2(author, botAccountId)) {
29446
+ console.log(`[Bitbucket] PR opened by the bot itself, skipping`);
29447
+ return { created: false };
29448
+ }
29449
+ const mentioned = detectMention2(pr.description, botAccountId);
29450
+ const reviewRequested = !!botAccountId && (pr.reviewers ?? []).some((r) => r.account_id === botAccountId);
29451
+ if (!mentioned && !reviewRequested) {
29452
+ console.log(`[Bitbucket] PR opened without bot mention or review request, skipping`);
29453
+ return { created: false };
29454
+ }
29455
+ const dedupKey = `bitbucket-pr-${repository.uuid}-${pr.id}-created`;
29456
+ const outcome = await withDedupReservation(dedupKey, async () => {
29457
+ const requestedByUserId = await resolveBitbucketSender(author, "pull_request", `PR #${pr.id}: ${pr.title}`);
29458
+ const context = pr.description ? extractMentionContext2(pr.description, botAccountId) : "";
29459
+ const templateId = mentioned ? "bitbucket.pull_request.opened" : "bitbucket.pull_request.review_requested";
29460
+ const result = resolveTemplate(templateId, {
29461
+ pr_id: pr.id,
29462
+ pr_title: pr.title,
29463
+ repo,
29464
+ username: await renderBitbucketIdentity(author),
29465
+ source_branch: pr.source?.branch?.name ?? "",
29466
+ target_branch: pr.destination?.branch?.name ?? "",
29467
+ pr_url: pullRequestWebUrl2(repo, pr),
29468
+ context_section: context ? `Context: ${context}
29469
+
29470
+ ` : ""
29471
+ });
29472
+ if (result.skipped) {
29473
+ return { created: false };
29474
+ }
29475
+ return createBitbucketTask(result.text, event, {
29476
+ taskType: "bitbucket-pr",
29477
+ vcsEventType: "pull_request",
29478
+ author,
29479
+ requestedByUserId
29480
+ });
29481
+ });
29482
+ if (!outcome)
29483
+ console.log(`[Bitbucket] Skipping duplicate PR event`);
29484
+ return outcome ?? { created: false };
29485
+ }
29486
+ async function handlePullRequestCommentCreated(body) {
29487
+ const event = pullRequestCommentEventOf(body);
29488
+ if (!event) {
29489
+ warnMalformed2("pullrequest:comment_created");
29490
+ return { created: false };
29491
+ }
29492
+ const { pullrequest: pr, repository, comment } = event;
29493
+ const repo = repository.full_name;
29494
+ const author = comment.user ?? event.actor;
29495
+ const botAccountId = await resolveBitbucketBotAccountId();
29496
+ if (isBot2(author, botAccountId)) {
29497
+ return { created: false };
29498
+ }
29499
+ if (!detectMention2(comment.content.raw, botAccountId)) {
29500
+ return { created: false };
29501
+ }
29502
+ console.log(`[Bitbucket] Comment by ${author.display_name} on PR #${pr.id} in ${repo}`);
29503
+ const dedupKey = `bitbucket-comment-${repository.uuid}-${pr.id}-${comment.id}`;
29504
+ const outcome = await withDedupReservation(dedupKey, async () => {
29505
+ const requestedByUserId = await resolveBitbucketSender(author, "pull_request_comment", comment.content.raw);
29506
+ const existingTask = await findTaskByVcs2(repo, pr.id, "bitbucket");
29507
+ const existingTaskNote = existingTask ? `
29508
+
29509
+ _Note: There's an active task (${existingTask.id}) for this PR #${pr.id}._` : "";
29510
+ const line = comment.inline?.to ?? comment.inline?.from;
29511
+ const locationSection = comment.inline ? `File: ${comment.inline.path}${line != null ? `:${line}` : ""}
29512
+ ` : "";
29513
+ const result = resolveTemplate("bitbucket.comment.mentioned", {
29514
+ pr_id: pr.id,
29515
+ pr_title: pr.title,
29516
+ username: await renderBitbucketIdentity(author),
29517
+ repo,
29518
+ pr_url: comment.links?.html?.href ?? pullRequestWebUrl2(repo, pr),
29519
+ location_section: locationSection,
29520
+ context: extractMentionContext2(comment.content.raw, botAccountId),
29521
+ existing_task_note: existingTaskNote
29522
+ });
29523
+ if (result.skipped) {
29524
+ return { created: false };
29525
+ }
29526
+ return createBitbucketTask(result.text, event, {
29527
+ taskType: "bitbucket-comment",
29528
+ vcsEventType: "pull_request_comment",
29529
+ author,
29530
+ requestedByUserId,
29531
+ vcsCommentId: comment.id,
29532
+ parentTaskId: existingTask?.id
29533
+ });
29534
+ });
29535
+ return outcome ?? { created: false };
29536
+ }
29537
+ async function handlePullRequestClosed(body, outcome) {
29538
+ const event = pullRequestEventOf(body);
29539
+ if (!event) {
29540
+ warnMalformed2(outcome === "merged" ? "pullrequest:fulfilled" : "pullrequest:rejected");
29541
+ return { created: false };
29542
+ }
29543
+ const { pullrequest: pr, repository } = event;
29544
+ const reason = outcome === "merged" ? "PR was merged" : "PR was declined";
29545
+ for (const task of await findActiveTasksByVcs2(repository.full_name, pr.id, "bitbucket")) {
29546
+ console.log(`[Bitbucket] Cancelling task ${task.id} — ${reason}`);
29547
+ await failTask2(task.id, reason);
29548
+ }
29549
+ return { created: false };
29550
+ }
29197
29551
  // src/github/handlers.ts
29198
29552
  init_db3();
29199
29553
  init_users();
@@ -29218,12 +29572,12 @@ function computeMentionPattern(names) {
29218
29572
  }
29219
29573
  var BOT_NAMES = computeBotNames();
29220
29574
  var MENTION_PATTERN = computeMentionPattern(BOT_NAMES);
29221
- function detectMention2(text) {
29575
+ function detectMention3(text) {
29222
29576
  if (!text)
29223
29577
  return false;
29224
29578
  return MENTION_PATTERN.test(text);
29225
29579
  }
29226
- function extractMentionContext2(text) {
29580
+ function extractMentionContext3(text) {
29227
29581
  if (!text)
29228
29582
  return "";
29229
29583
  return text.replace(MENTION_PATTERN, "").trim();
@@ -29666,7 +30020,7 @@ Related task: {{related_task_id}}
29666
30020
  });
29667
30021
 
29668
30022
  // src/github/handlers.ts
29669
- var processedEvents3 = new Map;
30023
+ var processedEvents4 = new Map;
29670
30024
  var EVENT_TTL2 = 60000;
29671
30025
  function buildGithubContextKey(fullName, kind, number) {
29672
30026
  const [owner, repo] = fullName.split("/");
@@ -29710,34 +30064,34 @@ function getCommandSuggestions(taskType, targetType) {
29710
30064
  return "";
29711
30065
  }
29712
30066
  }
29713
- function isDuplicate3(eventKey) {
30067
+ function isDuplicate4(eventKey) {
29714
30068
  const now = Date.now();
29715
- for (const [key, timestamp] of processedEvents3) {
30069
+ for (const [key, timestamp] of processedEvents4) {
29716
30070
  if (now - timestamp > EVENT_TTL2) {
29717
- processedEvents3.delete(key);
30071
+ processedEvents4.delete(key);
29718
30072
  }
29719
30073
  }
29720
- if (processedEvents3.has(eventKey)) {
30074
+ if (processedEvents4.has(eventKey)) {
29721
30075
  return true;
29722
30076
  }
29723
- processedEvents3.set(eventKey, now);
30077
+ processedEvents4.set(eventKey, now);
29724
30078
  return false;
29725
30079
  }
29726
- async function findLeadAgent3() {
30080
+ async function findLeadAgent4() {
29727
30081
  const agents = await getAllAgents2();
29728
30082
  const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
29729
30083
  if (onlineLead)
29730
30084
  return onlineLead;
29731
30085
  return agents.find((a) => a.isLead) ?? null;
29732
30086
  }
29733
- var UNMAPPED_NAMESPACE2 = "integration:unmapped:github";
29734
- var UNMAPPED_TTL_MS2 = 30 * 24 * 60 * 60 * 1000;
30087
+ var UNMAPPED_NAMESPACE3 = "integration:unmapped:github";
30088
+ var UNMAPPED_TTL_MS3 = 30 * 24 * 60 * 60 * 1000;
29735
30089
  async function resolveGitHubSender(login, sampleEventType, sampleContext) {
29736
30090
  const existing = await findUserByExternalId("github", login);
29737
30091
  if (existing)
29738
30092
  return existing.id;
29739
30093
  await upsertKv2({
29740
- namespace: UNMAPPED_NAMESPACE2,
30094
+ namespace: UNMAPPED_NAMESPACE3,
29741
30095
  key: `${login}:meta`,
29742
30096
  value: {
29743
30097
  lastSeenAt: new Date().toISOString(),
@@ -29745,9 +30099,9 @@ async function resolveGitHubSender(login, sampleEventType, sampleContext) {
29745
30099
  sampleContext: sampleContext.slice(0, 100)
29746
30100
  },
29747
30101
  valueType: "json",
29748
- expiresAt: Date.now() + UNMAPPED_TTL_MS2
30102
+ expiresAt: Date.now() + UNMAPPED_TTL_MS3
29749
30103
  });
29750
- await incrKv2(UNMAPPED_NAMESPACE2, `${login}:count`, 1);
30104
+ await incrKv2(UNMAPPED_NAMESPACE3, `${login}:count`, 1);
29751
30105
  return;
29752
30106
  }
29753
30107
  async function handlePullRequest(event) {
@@ -29766,10 +30120,10 @@ async function handlePullRequest(event) {
29766
30120
  return { created: false };
29767
30121
  }
29768
30122
  const eventKey = `pr-assigned:${repository.full_name}:${pr.number}`;
29769
- if (isDuplicate3(eventKey)) {
30123
+ if (isDuplicate4(eventKey)) {
29770
30124
  return { created: false };
29771
30125
  }
29772
- const lead = await findLeadAgent3();
30126
+ const lead = await findLeadAgent4();
29773
30127
  const result = resolveTemplate("github.pull_request.assigned", {
29774
30128
  pr_number: pr.number,
29775
30129
  pr_title: pr.title,
@@ -29816,7 +30170,7 @@ async function handlePullRequest(event) {
29816
30170
  console.log(`[GitHub] unassign cancel disabled by config — leaving task untouched (PR #${pr.number})`);
29817
30171
  return { created: false };
29818
30172
  }
29819
- const task = await findTaskByVcs2(repository.full_name, pr.number);
30173
+ const task = await findTaskByVcs2(repository.full_name, pr.number, "github");
29820
30174
  if (!task) {
29821
30175
  console.log(`[GitHub] No active task found for PR #${pr.number} to cancel`);
29822
30176
  return { created: false };
@@ -29833,15 +30187,15 @@ async function handlePullRequest(event) {
29833
30187
  return { created: false };
29834
30188
  }
29835
30189
  const eventKey = `pr-review-requested:${repository.full_name}:${pr.number}`;
29836
- if (isDuplicate3(eventKey)) {
30190
+ if (isDuplicate4(eventKey)) {
29837
30191
  return { created: false };
29838
30192
  }
29839
- const existingTask = await findTaskByVcs2(repository.full_name, pr.number);
30193
+ const existingTask = await findTaskByVcs2(repository.full_name, pr.number, "github");
29840
30194
  if (existingTask) {
29841
30195
  console.log(`[GitHub] Skipping review task for PR #${pr.number} — active task ${existingTask.id} already exists`);
29842
30196
  return { created: false };
29843
30197
  }
29844
- const lead = await findLeadAgent3();
30198
+ const lead = await findLeadAgent4();
29845
30199
  const result = resolveTemplate("github.pull_request.review_requested", {
29846
30200
  pr_number: pr.number,
29847
30201
  pr_title: pr.title,
@@ -29888,7 +30242,7 @@ async function handlePullRequest(event) {
29888
30242
  console.log(`[GitHub] review-request-removed cancel disabled by config — leaving task untouched (PR #${pr.number})`);
29889
30243
  return { created: false };
29890
30244
  }
29891
- const task = await findTaskByVcs2(repository.full_name, pr.number);
30245
+ const task = await findTaskByVcs2(repository.full_name, pr.number, "github");
29892
30246
  if (!task) {
29893
30247
  console.log(`[GitHub] No active task found for PR #${pr.number} to cancel`);
29894
30248
  return { created: false };
@@ -29906,10 +30260,10 @@ async function handlePullRequest(event) {
29906
30260
  return { created: false };
29907
30261
  }
29908
30262
  const eventKey = `pr-labeled:${repository.full_name}:${pr.number}:${labelName}`;
29909
- if (isDuplicate3(eventKey)) {
30263
+ if (isDuplicate4(eventKey)) {
29910
30264
  return { created: false };
29911
30265
  }
29912
- const lead = await findLeadAgent3();
30266
+ const lead = await findLeadAgent4();
29913
30267
  const result = resolveTemplate("github.pull_request.labeled", {
29914
30268
  pr_number: pr.number,
29915
30269
  pr_title: pr.title,
@@ -29959,16 +30313,16 @@ async function handlePullRequest(event) {
29959
30313
  if (action !== "opened" && action !== "edited") {
29960
30314
  return { created: false };
29961
30315
  }
29962
- const hasMention = detectMention2(pr.title) || detectMention2(pr.body);
30316
+ const hasMention = detectMention3(pr.title) || detectMention3(pr.body);
29963
30317
  if (!hasMention) {
29964
30318
  return { created: false };
29965
30319
  }
29966
30320
  const eventKey = `pr:${repository.full_name}:${pr.number}:${action}`;
29967
- if (isDuplicate3(eventKey)) {
30321
+ if (isDuplicate4(eventKey)) {
29968
30322
  return { created: false };
29969
30323
  }
29970
- const lead = await findLeadAgent3();
29971
- const context = extractMentionContext2(pr.body) || pr.title;
30324
+ const lead = await findLeadAgent4();
30325
+ const context = extractMentionContext3(pr.body) || pr.title;
29972
30326
  const result = resolveTemplate("github.pull_request.mentioned", {
29973
30327
  pr_number: pr.number,
29974
30328
  pr_title: pr.title,
@@ -30014,10 +30368,10 @@ async function handleIssue(event) {
30014
30368
  return { created: false };
30015
30369
  }
30016
30370
  const eventKey = `issue-assigned:${repository.full_name}:${issue.number}`;
30017
- if (isDuplicate3(eventKey)) {
30371
+ if (isDuplicate4(eventKey)) {
30018
30372
  return { created: false };
30019
30373
  }
30020
- const lead = await findLeadAgent3();
30374
+ const lead = await findLeadAgent4();
30021
30375
  const result = resolveTemplate("github.issue.assigned", {
30022
30376
  issue_number: issue.number,
30023
30377
  issue_title: issue.title,
@@ -30062,7 +30416,7 @@ async function handleIssue(event) {
30062
30416
  console.log(`[GitHub] unassign cancel disabled by config — leaving task untouched (issue #${issue.number})`);
30063
30417
  return { created: false };
30064
30418
  }
30065
- const task = await findTaskByVcs2(repository.full_name, issue.number);
30419
+ const task = await findTaskByVcs2(repository.full_name, issue.number, "github");
30066
30420
  if (!task) {
30067
30421
  console.log(`[GitHub] No active task found for issue #${issue.number} to cancel`);
30068
30422
  return { created: false };
@@ -30080,10 +30434,10 @@ async function handleIssue(event) {
30080
30434
  return { created: false };
30081
30435
  }
30082
30436
  const eventKey = `issue-labeled:${repository.full_name}:${issue.number}:${labelName}`;
30083
- if (isDuplicate3(eventKey)) {
30437
+ if (isDuplicate4(eventKey)) {
30084
30438
  return { created: false };
30085
30439
  }
30086
- const lead = await findLeadAgent3();
30440
+ const lead = await findLeadAgent4();
30087
30441
  const result = resolveTemplate("github.issue.labeled", {
30088
30442
  issue_number: issue.number,
30089
30443
  issue_title: issue.title,
@@ -30123,16 +30477,16 @@ async function handleIssue(event) {
30123
30477
  if (action !== "opened" && action !== "edited") {
30124
30478
  return { created: false };
30125
30479
  }
30126
- const hasMention = detectMention2(issue.title) || detectMention2(issue.body);
30480
+ const hasMention = detectMention3(issue.title) || detectMention3(issue.body);
30127
30481
  if (!hasMention) {
30128
30482
  return { created: false };
30129
30483
  }
30130
30484
  const eventKey = `issue:${repository.full_name}:${issue.number}:${action}`;
30131
- if (isDuplicate3(eventKey)) {
30485
+ if (isDuplicate4(eventKey)) {
30132
30486
  return { created: false };
30133
30487
  }
30134
- const lead = await findLeadAgent3();
30135
- const context = extractMentionContext2(issue.body) || issue.title;
30488
+ const lead = await findLeadAgent4();
30489
+ const context = extractMentionContext3(issue.body) || issue.title;
30136
30490
  const result = resolveTemplate("github.issue.mentioned", {
30137
30491
  issue_number: issue.number,
30138
30492
  issue_title: issue.title,
@@ -30178,21 +30532,21 @@ async function handleComment(event, eventType) {
30178
30532
  if (action !== "created") {
30179
30533
  return skip("action is not created");
30180
30534
  }
30181
- if (!detectMention2(comment.body)) {
30535
+ if (!detectMention3(comment.body)) {
30182
30536
  return skip("no bot mention");
30183
30537
  }
30184
30538
  const eventKey = `comment:${repository.full_name}:${comment.id}`;
30185
- if (isDuplicate3(eventKey)) {
30539
+ if (isDuplicate4(eventKey)) {
30186
30540
  return skip("duplicate delivery");
30187
30541
  }
30188
- const lead = await findLeadAgent3();
30542
+ const lead = await findLeadAgent4();
30189
30543
  const target = pull_request || issue;
30190
30544
  const targetType = pull_request ? "PR" : "Issue";
30191
30545
  const targetNumber = target?.number ?? 0;
30192
30546
  const targetTitle = target?.title ?? "Unknown";
30193
30547
  const targetUrl = target?.html_url ?? comment.html_url;
30194
- const existingTask = targetNumber ? await findTaskByVcs2(repository.full_name, targetNumber) : null;
30195
- const context = extractMentionContext2(comment.body);
30548
+ const existingTask = targetNumber ? await findTaskByVcs2(repository.full_name, targetNumber, "github") : null;
30549
+ const context = extractMentionContext3(comment.body);
30196
30550
  const suggestions = getCommandSuggestions("github-comment", targetType);
30197
30551
  const relatedTaskSection = existingTask ? `Related task: ${existingTask.id}
30198
30552
  \uD83D\uDD00 Consider routing to the same agent working on the related task.
@@ -30426,7 +30780,7 @@ async function handlePullRequestReview(event) {
30426
30780
  return { created: false };
30427
30781
  }
30428
30782
  const eventKey = `pr-review:${repository.full_name}:${pr.number}:${review.id}`;
30429
- if (isDuplicate3(eventKey)) {
30783
+ if (isDuplicate4(eventKey)) {
30430
30784
  return { created: false };
30431
30785
  }
30432
30786
  const { comments: inlineComments, degraded } = await fetchReviewComments(repository.full_name, pr.number, review.id, installation?.id);
@@ -30441,12 +30795,12 @@ async function handlePullRequestReview(event) {
30441
30795
  return { created: false };
30442
30796
  }
30443
30797
  }
30444
- const existingTask = await findTaskByVcs2(repository.full_name, pr.number);
30798
+ const existingTask = await findTaskByVcs2(repository.full_name, pr.number, "github");
30445
30799
  const isBotCreator = isBotAssignee(pr.user.login);
30446
30800
  if (!isBotCreator && !existingTask) {
30447
30801
  return { created: false };
30448
30802
  }
30449
- const lead = await findLeadAgent3();
30803
+ const lead = await findLeadAgent4();
30450
30804
  const { emoji, label } = getReviewStateInfo(review.state);
30451
30805
  const reviewBodySection = review.body ? `
30452
30806
 
@@ -30523,46 +30877,48 @@ async function handleWorkflowRun(event) {
30523
30877
  }
30524
30878
  // src/gitlab/auth.ts
30525
30879
  init_env_flag();
30526
- var initialized4 = false;
30527
- var webhookSecret4 = null;
30528
- var apiToken2 = null;
30880
+ var initialized5 = false;
30881
+ var webhookSecret5 = null;
30882
+ var apiToken3 = null;
30529
30883
  var gitlabUrl = "https://gitlab.com";
30530
30884
  function isGitLabEnabled() {
30531
30885
  return !!process.env.GITLAB_WEBHOOK_SECRET && !isEnvFlagEnabled("GITLAB_DISABLE", false);
30532
30886
  }
30533
30887
  function initGitLab() {
30534
- if (initialized4)
30888
+ if (initialized5)
30535
30889
  return;
30536
30890
  if (!isGitLabEnabled()) {
30537
30891
  console.log("[GitLab] Integration disabled (GITLAB_WEBHOOK_SECRET not set)");
30538
30892
  return;
30539
30893
  }
30540
- webhookSecret4 = process.env.GITLAB_WEBHOOK_SECRET;
30541
- apiToken2 = process.env.GITLAB_TOKEN ?? null;
30894
+ webhookSecret5 = process.env.GITLAB_WEBHOOK_SECRET;
30895
+ apiToken3 = process.env.GITLAB_TOKEN ?? null;
30542
30896
  gitlabUrl = process.env.GITLAB_URL ?? "https://gitlab.com";
30543
- initialized4 = true;
30897
+ initialized5 = true;
30544
30898
  console.log(`[GitLab] Integration initialized (url: ${gitlabUrl})`);
30545
30899
  }
30546
30900
  function verifyGitLabWebhook(tokenHeader) {
30547
- if (!webhookSecret4)
30901
+ if (!webhookSecret5)
30548
30902
  return false;
30549
30903
  if (!tokenHeader)
30550
30904
  return false;
30551
- if (tokenHeader.length !== webhookSecret4.length)
30905
+ if (tokenHeader.length !== webhookSecret5.length)
30552
30906
  return false;
30553
- return crypto.timingSafeEqual(Buffer.from(tokenHeader), Buffer.from(webhookSecret4));
30907
+ return crypto.timingSafeEqual(Buffer.from(tokenHeader), Buffer.from(webhookSecret5));
30554
30908
  }
30555
30909
  function getGitLabToken() {
30556
- return apiToken2;
30910
+ return apiToken3;
30557
30911
  }
30558
30912
  function getGitLabUrl() {
30559
30913
  return gitlabUrl;
30560
30914
  }
30561
- var GITLAB_BOT_NAME = process.env.GITLAB_BOT_NAME ?? "agent-swarm-bot";
30915
+ function getGitLabBotName() {
30916
+ return process.env.GITLAB_BOT_NAME || "agent-swarm-bot";
30917
+ }
30562
30918
  function resetGitLab() {
30563
- initialized4 = false;
30564
- webhookSecret4 = null;
30565
- apiToken2 = null;
30919
+ initialized5 = false;
30920
+ webhookSecret5 = null;
30921
+ apiToken3 = null;
30566
30922
  gitlabUrl = "https://gitlab.com";
30567
30923
  }
30568
30924
  // src/gitlab/handlers.ts
@@ -30572,7 +30928,7 @@ init_resolver();
30572
30928
  init_context_key();
30573
30929
 
30574
30930
  // src/gitlab/reactions.ts
30575
- function headers3() {
30931
+ function headers4() {
30576
30932
  const token = getGitLabToken();
30577
30933
  if (!token)
30578
30934
  throw new Error("[GitLab] No API token configured");
@@ -30593,7 +30949,7 @@ async function addGitLabReaction(project, entityType, iid, emojiName) {
30593
30949
  try {
30594
30950
  const resp = await fetch(url, {
30595
30951
  method: "POST",
30596
- headers: headers3(),
30952
+ headers: headers4(),
30597
30953
  body: JSON.stringify({ name: emojiName })
30598
30954
  });
30599
30955
  if (!resp.ok) {
@@ -30609,7 +30965,7 @@ async function addGitLabNoteReaction(project, entityType, iid, noteId, emojiName
30609
30965
  try {
30610
30966
  const resp = await fetch(url, {
30611
30967
  method: "POST",
30612
- headers: headers3(),
30968
+ headers: headers4(),
30613
30969
  body: JSON.stringify({ name: emojiName })
30614
30970
  });
30615
30971
  if (!resp.ok) {
@@ -30733,33 +31089,49 @@ The CI pipeline has failed. Please investigate and fix the issues.{{@template[co
30733
31089
  });
30734
31090
 
30735
31091
  // src/gitlab/handlers.ts
30736
- var processedEvents4 = new Map;
30737
- var DEDUP_TTL_MS2 = 60000;
30738
- function isDuplicate4(key) {
31092
+ var processedEvents5 = new Map;
31093
+ var DEDUP_TTL_MS3 = 60000;
31094
+ function isDuplicate5(key) {
30739
31095
  const now = Date.now();
30740
- for (const [k, ts] of processedEvents4) {
30741
- if (now - ts > DEDUP_TTL_MS2)
30742
- processedEvents4.delete(k);
31096
+ for (const [k, ts] of processedEvents5) {
31097
+ if (now - ts > DEDUP_TTL_MS3)
31098
+ processedEvents5.delete(k);
30743
31099
  }
30744
- if (processedEvents4.has(key))
31100
+ if (processedEvents5.has(key))
30745
31101
  return true;
30746
- processedEvents4.set(key, now);
31102
+ processedEvents5.set(key, now);
30747
31103
  return false;
30748
31104
  }
30749
- function detectMention3(text) {
31105
+ function detectMention4(text) {
30750
31106
  if (!text)
30751
31107
  return false;
30752
- return new RegExp(`@${GITLAB_BOT_NAME}\\b`, "i").test(text);
31108
+ return new RegExp(`@${getGitLabBotName()}\\b`, "i").test(text);
30753
31109
  }
30754
- function extractMentionContext3(text) {
30755
- return text.replace(new RegExp(`@${GITLAB_BOT_NAME}\\b`, "gi"), "").trim();
31110
+ function extractMentionContext4(text) {
31111
+ return text.replace(new RegExp(`@${getGitLabBotName()}\\b`, "gi"), "").trim();
30756
31112
  }
30757
- async function findLeadAgent4() {
31113
+ var LEGACY_SCOPE = {
31114
+ mr: {
31115
+ taskTypes: new Set(["gitlab-mr", "gitlab-ci"]),
31116
+ eventTypes: new Set(["merge_request", "note_on_mr", "pipeline"])
31117
+ },
31118
+ issue: {
31119
+ taskTypes: new Set(["gitlab-issue"]),
31120
+ eventTypes: new Set(["issue", "note_on_issue"])
31121
+ }
31122
+ };
31123
+ function isScopedTask(task, kind, contextKey) {
31124
+ if (task.contextKey)
31125
+ return task.contextKey === contextKey;
31126
+ const legacy = LEGACY_SCOPE[kind];
31127
+ return task.taskType !== undefined && legacy.taskTypes.has(task.taskType) || task.vcsEventType !== undefined && legacy.eventTypes.has(task.vcsEventType);
31128
+ }
31129
+ async function findLeadAgent5() {
30758
31130
  const agents = await getAllAgents2();
30759
31131
  return agents.find((a) => a.role === "lead" && a.status === "idle") ?? agents.find((a) => a.role === "lead") ?? null;
30760
31132
  }
30761
- var UNMAPPED_NAMESPACE3 = "integration:unmapped:gitlab";
30762
- var UNMAPPED_TTL_MS3 = 30 * 24 * 60 * 60 * 1000;
31133
+ var UNMAPPED_NAMESPACE4 = "integration:unmapped:gitlab";
31134
+ var UNMAPPED_TTL_MS4 = 30 * 24 * 60 * 60 * 1000;
30763
31135
  var GITLAB_WEBHOOK_ACTOR = { kind: "system", id: "webhook:gitlab" };
30764
31136
  async function resolveGitLabSender(user, sampleEventType, sampleContext) {
30765
31137
  const existing = await findUserByExternalId("gitlab", user.username);
@@ -30772,7 +31144,7 @@ async function resolveGitLabSender(user, sampleEventType, sampleContext) {
30772
31144
  return linked.id;
30773
31145
  }
30774
31146
  await upsertKv2({
30775
- namespace: UNMAPPED_NAMESPACE3,
31147
+ namespace: UNMAPPED_NAMESPACE4,
30776
31148
  key: `${user.username}:meta`,
30777
31149
  value: {
30778
31150
  lastSeenAt: new Date().toISOString(),
@@ -30780,9 +31152,9 @@ async function resolveGitLabSender(user, sampleEventType, sampleContext) {
30780
31152
  sampleContext: sampleContext.slice(0, 100)
30781
31153
  },
30782
31154
  valueType: "json",
30783
- expiresAt: Date.now() + UNMAPPED_TTL_MS3
31155
+ expiresAt: Date.now() + UNMAPPED_TTL_MS4
30784
31156
  });
30785
- await incrKv2(UNMAPPED_NAMESPACE3, `${user.username}:count`, 1);
31157
+ await incrKv2(UNMAPPED_NAMESPACE4, `${user.username}:count`, 1);
30786
31158
  return;
30787
31159
  }
30788
31160
  async function renderGitLabIdentity(username) {
@@ -30795,19 +31167,19 @@ async function handleMergeRequest(event) {
30795
31167
  const requestedByUserId = await resolveGitLabSender(user, "merge_request", `MR !${mr.iid}: ${mr.title}`);
30796
31168
  console.log(`[GitLab] MR #${mr.iid} ${action} by ${user.username} in ${repo}`);
30797
31169
  const dedupKey = `gitlab-mr-${repo}-${mr.iid}-${action}-${user.username}`;
30798
- if (isDuplicate4(dedupKey)) {
31170
+ if (isDuplicate5(dedupKey)) {
30799
31171
  console.log(`[GitLab] Skipping duplicate MR event`);
30800
31172
  return { created: false };
30801
31173
  }
30802
- const lead = await findLeadAgent4();
31174
+ const lead = await findLeadAgent5();
30803
31175
  switch (action) {
30804
31176
  case "open": {
30805
- const hasMention = detectMention3(mr.description);
31177
+ const hasMention = detectMention4(mr.description);
30806
31178
  if (!hasMention) {
30807
31179
  console.log(`[GitLab] MR opened without bot mention, skipping`);
30808
31180
  return { created: false };
30809
31181
  }
30810
- const context = mr.description ? extractMentionContext3(mr.description) : "";
31182
+ const context = mr.description ? extractMentionContext4(mr.description) : "";
30811
31183
  const contextSection = context ? `Context: ${context}
30812
31184
 
30813
31185
  ` : "";
@@ -30851,16 +31223,21 @@ async function handleMergeRequest(event) {
30851
31223
  }
30852
31224
  case "close":
30853
31225
  case "merge": {
30854
- const existingTask = await findTaskByVcs2(repo, mr.iid);
30855
- if (existingTask) {
30856
- const reason = action === "merge" ? "MR was merged" : "MR was closed";
30857
- console.log(`[GitLab] Cancelling task ${existingTask.id} — ${reason}`);
30858
- await failTask2(existingTask.id, reason);
31226
+ const reason = action === "merge" ? "MR was merged" : "MR was closed";
31227
+ const mrContextKey = gitlabContextKey({
31228
+ projectId: String(project.id),
31229
+ kind: "mr",
31230
+ iid: mr.iid
31231
+ });
31232
+ const tasks = await findActiveTasksByVcs2(repo, mr.iid, "gitlab");
31233
+ for (const task of tasks.filter((t) => isScopedTask(t, "mr", mrContextKey))) {
31234
+ console.log(`[GitLab] Cancelling task ${task.id} — ${reason}`);
31235
+ await failTask2(task.id, reason);
30859
31236
  }
30860
31237
  return { created: false };
30861
31238
  }
30862
31239
  case "update": {
30863
- const task = await findTaskByVcs2(repo, mr.iid);
31240
+ const task = await findTaskByVcs2(repo, mr.iid, "gitlab");
30864
31241
  if (task) {
30865
31242
  console.log(`[GitLab] MR #${mr.iid} updated, active task exists: ${task.id}`);
30866
31243
  return { created: false };
@@ -30879,21 +31256,21 @@ async function handleIssue2(event) {
30879
31256
  const requestedByUserId = await resolveGitLabSender(user, "issue", `Issue #${issue.iid}: ${issue.title}`);
30880
31257
  console.log(`[GitLab] Issue #${issue.iid} ${action} by ${user.username} in ${repo}`);
30881
31258
  const dedupKey = `gitlab-issue-${repo}-${issue.iid}-${action}-${user.username}`;
30882
- if (isDuplicate4(dedupKey)) {
31259
+ if (isDuplicate5(dedupKey)) {
30883
31260
  return { created: false };
30884
31261
  }
30885
- const lead = await findLeadAgent4();
31262
+ const lead = await findLeadAgent5();
30886
31263
  switch (action) {
30887
31264
  case "open": {
30888
- const hasMention = detectMention3(issue.description);
31265
+ const hasMention = detectMention4(issue.description);
30889
31266
  if (!hasMention) {
30890
- const isBotAssigned = event.assignees?.some((a) => a.username.toLowerCase() === GITLAB_BOT_NAME.toLowerCase());
31267
+ const isBotAssigned = event.assignees?.some((a) => a.username.toLowerCase() === getGitLabBotName().toLowerCase());
30891
31268
  if (!isBotAssigned) {
30892
31269
  console.log(`[GitLab] Issue opened without bot mention/assignment, skipping`);
30893
31270
  return { created: false };
30894
31271
  }
30895
31272
  }
30896
- const context = issue.description ? extractMentionContext3(issue.description) : "";
31273
+ const context = issue.description ? extractMentionContext4(issue.description) : "";
30897
31274
  const contextSection = context ? `Context: ${context}
30898
31275
 
30899
31276
  ` : "";
@@ -30934,7 +31311,12 @@ async function handleIssue2(event) {
30934
31311
  return { created: true, taskId: task.id };
30935
31312
  }
30936
31313
  case "close": {
30937
- const existingTask = await findTaskByVcs2(repo, issue.iid);
31314
+ const issueContextKey = gitlabContextKey({
31315
+ projectId: String(project.id),
31316
+ kind: "issue",
31317
+ iid: issue.iid
31318
+ });
31319
+ const existingTask = (await findActiveTasksByVcs2(repo, issue.iid, "gitlab")).find((t) => isScopedTask(t, "issue", issueContextKey));
30938
31320
  if (existingTask) {
30939
31321
  console.log(`[GitLab] Cancelling task ${existingTask.id} — issue closed`);
30940
31322
  await failTask2(existingTask.id, "Issue was closed");
@@ -30949,16 +31331,16 @@ async function handleNote(event) {
30949
31331
  const { user, project, object_attributes: note } = event;
30950
31332
  const repo = project.path_with_namespace;
30951
31333
  const requestedByUserId = await resolveGitLabSender(user, "note", note.note);
30952
- if (!detectMention3(note.note)) {
31334
+ if (!detectMention4(note.note)) {
30953
31335
  return { created: false };
30954
31336
  }
30955
31337
  console.log(`[GitLab] Note by ${user.username} in ${repo} (${note.noteable_type})`);
30956
31338
  const dedupKey = `gitlab-note-${note.id}`;
30957
- if (isDuplicate4(dedupKey)) {
31339
+ if (isDuplicate5(dedupKey)) {
30958
31340
  return { created: false };
30959
31341
  }
30960
- const lead = await findLeadAgent4();
30961
- const context = extractMentionContext3(note.note);
31342
+ const lead = await findLeadAgent5();
31343
+ const context = extractMentionContext4(note.note);
30962
31344
  let targetNumber;
30963
31345
  let targetUrl;
30964
31346
  let eventType;
@@ -30977,7 +31359,7 @@ async function handleNote(event) {
30977
31359
  console.log(`[GitLab] Ignoring note on ${note.noteable_type}`);
30978
31360
  return { created: false };
30979
31361
  }
30980
- const existingTask = targetNumber ? await findTaskByVcs2(repo, targetNumber) : null;
31362
+ const existingTask = targetNumber ? await findTaskByVcs2(repo, targetNumber, "gitlab") : null;
30981
31363
  const existingTaskNote = existingTask ? `
30982
31364
 
30983
31365
  _Note: There's an active task (${existingTask.id}) for this ${entityLabel}._` : "";
@@ -31032,14 +31414,14 @@ async function handlePipeline(event) {
31032
31414
  }
31033
31415
  const mrIid = event.merge_request.iid;
31034
31416
  const dedupKey = `gitlab-pipeline-${pipeline.id}`;
31035
- if (isDuplicate4(dedupKey)) {
31417
+ if (isDuplicate5(dedupKey)) {
31036
31418
  return { created: false };
31037
31419
  }
31038
- const existingTask = await findTaskByVcs2(repo, mrIid);
31420
+ const existingTask = await findTaskByVcs2(repo, mrIid, "gitlab");
31039
31421
  if (!existingTask) {
31040
31422
  return { created: false };
31041
31423
  }
31042
- const lead = await findLeadAgent4();
31424
+ const lead = await findLeadAgent5();
31043
31425
  const pipelineResult = resolveTemplate("gitlab.pipeline.failed", {
31044
31426
  pipeline_id: pipeline.id,
31045
31427
  mr_iid: mrIid,
@@ -31243,6 +31625,71 @@ function readApiUrlOverrides() {
31243
31625
  }
31244
31626
  }
31245
31627
 
31628
+ // src/integrations/chat-sdk/facts.ts
31629
+ var SNIPPET_MAX = 80;
31630
+ function snippet2(text) {
31631
+ const flat = text?.replace(/\s+/g, " ").trim();
31632
+ if (!flat)
31633
+ return;
31634
+ return flat.length > SNIPPET_MAX ? `${flat.slice(0, SNIPPET_MAX)}...` : flat;
31635
+ }
31636
+ function personLabel(name, username, fallback) {
31637
+ if (name && username && name !== username)
31638
+ return `${name} (@${username})`;
31639
+ if (username)
31640
+ return `@${username}`;
31641
+ return name || fallback;
31642
+ }
31643
+ function replyIsTopicRoot(raw) {
31644
+ const reply = raw.reply_to_message;
31645
+ return reply !== undefined && (reply.forum_topic_created !== undefined || raw.is_topic_message === true && reply.message_id === raw.message_thread_id);
31646
+ }
31647
+ function isTelegramReplyToBot(raw, botUserId) {
31648
+ const fromId = raw.reply_to_message?.from?.id;
31649
+ return !replyIsTopicRoot(raw) && fromId !== undefined && botUserId !== undefined && String(fromId) === botUserId;
31650
+ }
31651
+ function telegramFacts(raw, message, botUserId) {
31652
+ const reply = raw.reply_to_message;
31653
+ const topicRoot = replyIsTopicRoot(raw);
31654
+ const realReply = reply && !topicRoot ? reply : undefined;
31655
+ const topicName = topicRoot ? reply?.forum_topic_created?.name : undefined;
31656
+ const name = [raw.from?.first_name, raw.from?.last_name].filter(Boolean).join(" ").trim();
31657
+ return {
31658
+ chatType: raw.chat?.type,
31659
+ isForum: raw.chat?.is_forum === true ? true : undefined,
31660
+ title: raw.chat?.title,
31661
+ topic: raw.is_topic_message === true && raw.message_thread_id !== undefined ? topicName ? `"${topicName}"` : `#${raw.message_thread_id}` : undefined,
31662
+ from: personLabel(name || undefined, raw.from?.username, message.author.userId),
31663
+ replyToBot: isTelegramReplyToBot(raw, botUserId),
31664
+ replyToSnippet: snippet2(realReply?.text ?? realReply?.caption)
31665
+ };
31666
+ }
31667
+ function readChatMessageFacts(thread, message) {
31668
+ const raw = message.raw;
31669
+ if (thread.adapter.name === "telegram" && raw && typeof raw === "object") {
31670
+ return telegramFacts(raw, message, thread.adapter.botUserId);
31671
+ }
31672
+ const { fullName, userName, userId } = message.author;
31673
+ return {
31674
+ chatType: thread.isDM ? "dm" : undefined,
31675
+ from: personLabel(fullName || undefined, userName || undefined, userId),
31676
+ replyToBot: message.replyTo?.author.isMe === true,
31677
+ replyToSnippet: snippet2(message.replyTo?.text)
31678
+ };
31679
+ }
31680
+ function formatChatHeaderFacts(adapter, facts, addressed) {
31681
+ const oneLine = (text) => text.replace(/\s+/g, " ").trim();
31682
+ const parts = [adapter];
31683
+ if (facts.chatType)
31684
+ parts.push(facts.title ? `${facts.chatType} "${oneLine(facts.title)}"` : facts.chatType);
31685
+ if (facts.isForum)
31686
+ parts.push(facts.topic ? `forum topic ${oneLine(facts.topic)}` : "forum");
31687
+ parts.push(`from: ${oneLine(facts.from)}`, `addressed: ${addressed}`);
31688
+ if (facts.replyToSnippet)
31689
+ parts.push(`reply-to: "${facts.replyToSnippet}"`);
31690
+ return parts.join(" · ");
31691
+ }
31692
+
31246
31693
  // src/integrations/chat-sdk/logger.ts
31247
31694
  init_secret_scrubber();
31248
31695
  var MAX_ISSUE_CHARS = 300;
@@ -31334,8 +31781,14 @@ async function loadAdapter(name, config, logger) {
31334
31781
  const base = { ...config, apiUrl, logger };
31335
31782
  switch (name) {
31336
31783
  case "telegram": {
31337
- const { createTelegramAdapter } = await import("./index-g216q6jr.js");
31338
- return createTelegramAdapter({
31784
+ const { TelegramAdapter } = await import("./index-zsyx51ap.js");
31785
+
31786
+ class SwarmTelegramAdapter extends TelegramAdapter {
31787
+ isBotMentioned(message, text) {
31788
+ return super.isBotMentioned(message, text) || String(message.from?.id) !== this.botUserId && isTelegramReplyToBot(message, this.botUserId);
31789
+ }
31790
+ }
31791
+ return new SwarmTelegramAdapter({
31339
31792
  ...base,
31340
31793
  allowUnverifiedWebhooks: false,
31341
31794
  mentionOnReply: true
@@ -32383,63 +32836,6 @@ async function attachChatFilesToTask(taskId, fetched) {
32383
32836
  return unattached;
32384
32837
  }
32385
32838
 
32386
- // src/integrations/chat-sdk/facts.ts
32387
- var SNIPPET_MAX = 80;
32388
- function snippet2(text) {
32389
- const flat = text?.replace(/\s+/g, " ").trim();
32390
- if (!flat)
32391
- return;
32392
- return flat.length > SNIPPET_MAX ? `${flat.slice(0, SNIPPET_MAX)}...` : flat;
32393
- }
32394
- function personLabel(name, username, fallback) {
32395
- if (name && username && name !== username)
32396
- return `${name} (@${username})`;
32397
- if (username)
32398
- return `@${username}`;
32399
- return name || fallback;
32400
- }
32401
- function telegramFacts(raw, message, botUserId) {
32402
- const reply = raw.reply_to_message;
32403
- const replyIsTopicRoot = reply !== undefined && (reply.forum_topic_created !== undefined || raw.is_topic_message === true && reply.message_id === raw.message_thread_id);
32404
- const realReply = reply && !replyIsTopicRoot ? reply : undefined;
32405
- const topicName = replyIsTopicRoot ? reply?.forum_topic_created?.name : undefined;
32406
- const name = [raw.from?.first_name, raw.from?.last_name].filter(Boolean).join(" ").trim();
32407
- return {
32408
- chatType: raw.chat?.type,
32409
- isForum: raw.chat?.is_forum === true ? true : undefined,
32410
- title: raw.chat?.title,
32411
- topic: raw.is_topic_message === true && raw.message_thread_id !== undefined ? topicName ? `"${topicName}"` : `#${raw.message_thread_id}` : undefined,
32412
- from: personLabel(name || undefined, raw.from?.username, message.author.userId),
32413
- replyToBot: realReply?.from?.id !== undefined && botUserId !== undefined && String(realReply.from.id) === botUserId,
32414
- replyToSnippet: snippet2(realReply?.text ?? realReply?.caption)
32415
- };
32416
- }
32417
- function readChatMessageFacts(thread, message) {
32418
- const raw = message.raw;
32419
- if (thread.adapter.name === "telegram" && raw && typeof raw === "object") {
32420
- return telegramFacts(raw, message, thread.adapter.botUserId);
32421
- }
32422
- const { fullName, userName, userId } = message.author;
32423
- return {
32424
- chatType: thread.isDM ? "dm" : undefined,
32425
- from: personLabel(fullName || undefined, userName || undefined, userId),
32426
- replyToBot: message.replyTo?.author.isMe === true,
32427
- replyToSnippet: snippet2(message.replyTo?.text)
32428
- };
32429
- }
32430
- function formatChatHeaderFacts(adapter, facts, addressed) {
32431
- const oneLine = (text) => text.replace(/\s+/g, " ").trim();
32432
- const parts = [adapter];
32433
- if (facts.chatType)
32434
- parts.push(facts.title ? `${facts.chatType} "${oneLine(facts.title)}"` : facts.chatType);
32435
- if (facts.isForum)
32436
- parts.push(facts.topic ? `forum topic ${oneLine(facts.topic)}` : "forum");
32437
- parts.push(`from: ${oneLine(facts.from)}`, `addressed: ${addressed}`);
32438
- if (facts.replyToSnippet)
32439
- parts.push(`reply-to: "${facts.replyToSnippet}"`);
32440
- return parts.join(" · ");
32441
- }
32442
-
32443
32839
  // src/integrations/chat-sdk/outbound.ts
32444
32840
  init_secret_scrubber();
32445
32841
  init_event_bus();
@@ -32515,11 +32911,32 @@ class ChatFileTooLargeError extends Error {
32515
32911
  this.name = "ChatFileTooLargeError";
32516
32912
  }
32517
32913
  }
32914
+ var FENCE_LINE = /^ {0,3}(`{3,}|~{3,})/;
32915
+ var NON_HEADING_HASH = /^( {0,3}(?:>[ \t]?)*[ \t]*(?:(?:[-*+]|\d{1,9}[.)])[ \t]+(?:\[[ xX]\][ \t]+)?)?)(#{7,}|#{1,6}(?=[^\s#]))/;
32916
+ function escapeTelegramHashLines(markdown) {
32917
+ let fence;
32918
+ return markdown.split(`
32919
+ `).map((line) => {
32920
+ const marker = FENCE_LINE.exec(line)?.[1];
32921
+ if (fence) {
32922
+ if (marker && marker[0] === fence[0] && marker.length >= fence.length)
32923
+ fence = undefined;
32924
+ return line;
32925
+ }
32926
+ if (marker) {
32927
+ fence = marker;
32928
+ return line;
32929
+ }
32930
+ return line.replace(NON_HEADING_HASH, "$1\\$2");
32931
+ }).join(`
32932
+ `);
32933
+ }
32518
32934
  async function postChunks(adapter, target, text) {
32519
32935
  const messageIds = [];
32520
32936
  let threadId;
32521
32937
  for (const chunk of splitChatMessage(text, chatMessageLimit(adapter))) {
32522
- const sent = await target.post({ markdown: chunk });
32938
+ const markdown = adapter === "telegram" ? escapeTelegramHashLines(chunk) : chunk;
32939
+ const sent = await target.post({ markdown });
32523
32940
  messageIds.push(sent.id);
32524
32941
  threadId ??= sent.threadId;
32525
32942
  }
@@ -34251,7 +34668,7 @@ async function resolveBotAccountId() {
34251
34668
  function resetBotAccountIdCache() {
34252
34669
  setCachedBotAccountId(null);
34253
34670
  }
34254
- async function findLeadAgent5() {
34671
+ async function findLeadAgent6() {
34255
34672
  const agents = await getAllAgents2();
34256
34673
  const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
34257
34674
  if (onlineLead)
@@ -34455,7 +34872,7 @@ async function handleIssueDeleteEvent(event) {
34455
34872
  }
34456
34873
  }
34457
34874
  async function createInitialJiraTask(input) {
34458
- const lead = await findLeadAgent5();
34875
+ const lead = await findLeadAgent6();
34459
34876
  const descriptionSection = input.descriptionText ? `
34460
34877
  Description:
34461
34878
  ${input.descriptionText}
@@ -34493,7 +34910,7 @@ ${input.descriptionText}
34493
34910
  console.log(`[Jira Sync] Created ${action} task ${task.id} for ${input.issueKey} -> ${lead?.name ?? "unassigned"}`);
34494
34911
  }
34495
34912
  async function createCommentMentionTask(input) {
34496
- const lead = await findLeadAgent5();
34913
+ const lead = await findLeadAgent6();
34497
34914
  const descriptionSection = input.descriptionText ? `
34498
34915
  Description:
34499
34916
  ${input.descriptionText}
@@ -34553,7 +34970,7 @@ async function notifySlack(text) {
34553
34970
  return;
34554
34971
  }
34555
34972
  try {
34556
- const { getSlackApp } = await import("./app-353vre8g.js");
34973
+ const { getSlackApp } = await import("./app-nndcvftq.js");
34557
34974
  const app = getSlackApp();
34558
34975
  if (!app) {
34559
34976
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -34624,7 +35041,7 @@ async function deleteJiraWebhook(webhookId) {
34624
35041
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
34625
35042
  }
34626
35043
  async function overwriteWebhookIds(next) {
34627
- const { getDbClient } = await import("./db-6sfrn9g3.js");
35044
+ const { getDbClient } = await import("./db-88wcymxt.js");
34628
35045
  await getDbClient().transaction(async (tx) => {
34629
35046
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
34630
35047
  if (!row) {
@@ -34731,7 +35148,7 @@ function stopJiraWebhookKeepalive() {
34731
35148
  }
34732
35149
 
34733
35150
  // src/jira/app.ts
34734
- var initialized5 = false;
35151
+ var initialized6 = false;
34735
35152
  function isJiraEnabled() {
34736
35153
  if (isEnvFlagEnabled("JIRA_DISABLE", false))
34737
35154
  return false;
@@ -34743,12 +35160,12 @@ function resetJira() {
34743
35160
  resetBotAccountIdCache();
34744
35161
  teardownJiraOutboundSync();
34745
35162
  stopJiraWebhookKeepalive();
34746
- initialized5 = false;
35163
+ initialized6 = false;
34747
35164
  }
34748
35165
  async function initJira() {
34749
- if (initialized5)
35166
+ if (initialized6)
34750
35167
  return isJiraEnabled();
34751
- initialized5 = true;
35168
+ initialized6 = true;
34752
35169
  if (!isJiraEnabled()) {
34753
35170
  console.log("[Jira] Integration disabled or JIRA_CLIENT_ID not set");
34754
35171
  return false;
@@ -34805,7 +35222,7 @@ function synthesizeDeliveryId(body, rawBody) {
34805
35222
  const hash = createHash2("sha256").update(rawBody).digest("hex").slice(0, 16);
34806
35223
  return `${event}:${ts}:${entityId}:${hash}`;
34807
35224
  }
34808
- async function isDuplicateDelivery(deliveryId) {
35225
+ async function isDuplicateDelivery2(deliveryId) {
34809
35226
  return await hasTrackerDelivery("jira", deliveryId);
34810
35227
  }
34811
35228
  async function markDelivery(externalId, deliveryId) {
@@ -34828,7 +35245,7 @@ async function handleJiraWebhook(pathToken, rawBody) {
34828
35245
  return { status: 200, body: { status: "ignored", reason: "invalid-json" } };
34829
35246
  }
34830
35247
  const deliveryId = synthesizeDeliveryId(parsed, rawBody);
34831
- if (await isDuplicateDelivery(deliveryId)) {
35248
+ if (await isDuplicateDelivery2(deliveryId)) {
34832
35249
  return { status: 200, body: { status: "duplicate" } };
34833
35250
  }
34834
35251
  const event = String(parsed.webhookEvent ?? "");
@@ -106647,15 +107064,15 @@ async function _fetchIssueGatingInfo(issueId) {
106647
107064
  const labelNames = (json.data?.issue?.labels?.nodes ?? []).map((n) => n?.name ?? "").filter((n) => n.length > 0);
106648
107065
  return { stateType, labelNames };
106649
107066
  }
106650
- async function findLeadAgent6() {
107067
+ async function findLeadAgent7() {
106651
107068
  const agents = await getAllAgents2();
106652
107069
  const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
106653
107070
  if (onlineLead)
106654
107071
  return onlineLead;
106655
107072
  return agents.find((a) => a.isLead) ?? null;
106656
107073
  }
106657
- var UNMAPPED_NAMESPACE4 = "integration:unmapped:linear";
106658
- var UNMAPPED_TTL_MS4 = 30 * 24 * 60 * 60 * 1000;
107074
+ var UNMAPPED_NAMESPACE5 = "integration:unmapped:linear";
107075
+ var UNMAPPED_TTL_MS5 = 30 * 24 * 60 * 60 * 1000;
106659
107076
  var LINEAR_WEBHOOK_ACTOR = { kind: "system", id: "webhook:linear" };
106660
107077
  var APP_USER_ID_NAMESPACE = "integration:linear:bot-app-user-id";
106661
107078
  async function getStoredAppUserId(workspaceId) {
@@ -106686,7 +107103,7 @@ async function resolveLinearActor(linearUserId, email, name, workspaceId, sample
106686
107103
  return linked.id;
106687
107104
  }
106688
107105
  await upsertKv2({
106689
- namespace: UNMAPPED_NAMESPACE4,
107106
+ namespace: UNMAPPED_NAMESPACE5,
106690
107107
  key: `${linearUserId}:meta`,
106691
107108
  value: {
106692
107109
  lastSeenAt: new Date().toISOString(),
@@ -106694,9 +107111,9 @@ async function resolveLinearActor(linearUserId, email, name, workspaceId, sample
106694
107111
  sampleContext: sampleContext ? sampleContext.slice(0, 100) : null
106695
107112
  },
106696
107113
  valueType: "json",
106697
- expiresAt: Date.now() + UNMAPPED_TTL_MS4
107114
+ expiresAt: Date.now() + UNMAPPED_TTL_MS5
106698
107115
  });
106699
- await incrKv2(UNMAPPED_NAMESPACE4, `${linearUserId}:count`, 1);
107116
+ await incrKv2(UNMAPPED_NAMESPACE5, `${linearUserId}:count`, 1);
106700
107117
  return;
106701
107118
  }
106702
107119
  var REQUEST_SECTION_LABEL = "Request (comment that opened this session)";
@@ -106808,7 +107225,7 @@ async function handleAgentSessionEvent(event) {
106808
107225
  }
106809
107226
  return;
106810
107227
  }
106811
- const lead = await findLeadAgent6();
107228
+ const lead = await findLeadAgent7();
106812
107229
  const sessionSection = sessionUrl ? `
106813
107230
  Session: ${sessionUrl}` : "";
106814
107231
  const requestSection = buildSessionRequestSection(event, actorName);
@@ -107012,7 +107429,7 @@ async function handleAgentSessionPrompted(event) {
107012
107429
  return;
107013
107430
  }
107014
107431
  }
107015
- const lead = await findLeadAgent6();
107432
+ const lead = await findLeadAgent7();
107016
107433
  const activity = event.agentActivity;
107017
107434
  const promptUser = activity?.user;
107018
107435
  const promptedActorLinearId = promptUser ? String(promptUser.id ?? "") : "";
@@ -107294,7 +107711,7 @@ function shouldSkipForLoopPrevention2(sync) {
107294
107711
  }
107295
107712
 
107296
107713
  // src/linear/app.ts
107297
- var initialized6 = false;
107714
+ var initialized7 = false;
107298
107715
  var unsubscribeRefresh = null;
107299
107716
  function isLinearEnabled() {
107300
107717
  if (isEnvFlagEnabled("LINEAR_DISABLE", false))
@@ -107309,12 +107726,12 @@ function resetLinear() {
107309
107726
  unsubscribeRefresh();
107310
107727
  unsubscribeRefresh = null;
107311
107728
  }
107312
- initialized6 = false;
107729
+ initialized7 = false;
107313
107730
  }
107314
107731
  async function initLinear() {
107315
- if (initialized6)
107732
+ if (initialized7)
107316
107733
  return isLinearEnabled();
107317
- initialized6 = true;
107734
+ initialized7 = true;
107318
107735
  if (!isLinearEnabled()) {
107319
107736
  console.log("[Linear] Integration disabled or LINEAR_CLIENT_ID not set");
107320
107737
  return false;
@@ -108019,7 +108436,7 @@ async function reloadGlobalConfigsAndIntegrations() {
108019
108436
  return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
108020
108437
  }
108021
108438
  async function reloadGlobalConfigsAndIntegrationsInner() {
108022
- const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-arytgj5q.js");
108439
+ const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-5en23s5z.js");
108023
108440
  const wasEmbeddingsConfigured = getEmbeddingProvider().isConfigured();
108024
108441
  const updated = await loadGlobalConfigsIntoEnv(true);
108025
108442
  await syncTelemetryEnabled("settings").catch((err) => {
@@ -108035,10 +108452,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
108035
108452
  integrations.push("embeddings");
108036
108453
  }
108037
108454
  if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
108038
- import("./boot-reembed-b9c3az3c.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
108455
+ import("./boot-reembed-r8rhf9h8.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
108039
108456
  console.error("[config-reload] memory backfill failed (non-fatal):", err);
108040
108457
  });
108041
- import("./boot-reembed-qdkvxeem.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
108458
+ import("./boot-reembed-vwcj2y5d.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
108042
108459
  console.error("[config-reload] script backfill failed (non-fatal):", err);
108043
108460
  });
108044
108461
  }
@@ -108060,6 +108477,11 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
108060
108477
  teardownAzureDevOpsOutbound();
108061
108478
  if (isAzureDevOpsEnabled())
108062
108479
  initAzureDevOpsOutbound();
108480
+ resetBitbucket();
108481
+ resetBitbucketBotCache();
108482
+ initBitbucket();
108483
+ if (isBitbucketEnabled())
108484
+ integrations.push("bitbucket");
108063
108485
  resetLinear();
108064
108486
  if (await initLinear())
108065
108487
  integrations.push("linear");
@@ -115538,14 +115960,14 @@ var prMatcher = (content) => {
115538
115960
  }
115539
115961
  return results;
115540
115962
  };
115541
- function escapeRegExp2(value) {
115963
+ function escapeRegExp3(value) {
115542
115964
  return value.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
115543
115965
  }
115544
115966
  function agentFsPathRegex() {
115545
115967
  const appHosts = getConfiguredAppUrls().flatMap((value) => {
115546
115968
  try {
115547
115969
  const url = new URL(value);
115548
- return [escapeRegExp2(`${url.host}${url.pathname.replace(/\/+$/, "")}`)];
115970
+ return [escapeRegExp3(`${url.host}${url.pathname.replace(/\/+$/, "")}`)];
115549
115971
  } catch {
115550
115972
  return [];
115551
115973
  }
@@ -130365,7 +130787,7 @@ var registerScriptConnectionsTool = (server) => {
130365
130787
  };
130366
130788
  // src/tools/script-delete.ts
130367
130789
  init_zod();
130368
- var SCRIPT_DELETE_DESCRIPTION = "Remove a swarm-shared script from the catalog. Versions table preserves history.";
130790
+ var SCRIPT_DELETE_DESCRIPTION = "Permanently remove a swarm-shared script and all its versions from the catalog. This cannot be undone.";
130369
130791
  var registerScriptDeleteTool = (server) => {
130370
130792
  createToolRegistrar(server)("script-delete", {
130371
130793
  title: "Script Delete",
@@ -134934,7 +135356,7 @@ async function emitBudgetRefusalSideEffects(ctx, inserted) {
134934
135356
  console.warn(`[budget-refusal-notify] Failed to create follow-up task for budget refusal (task=${ctx.task.id.slice(0, 8)}): ${err}`);
134935
135357
  }
134936
135358
  }
134937
- import("./event-bus-9vpk8gmq.js").then(({ workflowEventBus }) => {
135359
+ import("./event-bus-3z78ep5n.js").then(({ workflowEventBus }) => {
134938
135360
  workflowEventBus.emit("task.budget_refused", {
134939
135361
  taskId: ctx.task.id,
134940
135362
  agentId: ctx.agentId,
@@ -135985,7 +136407,7 @@ var registerCreateWorkflowTool = (server) => {
135985
136407
  ` + "- CROSS-NODE DATA: To use output from an upstream node, you MUST declare an 'inputs' mapping on the downstream node. " + 'Example: inputs: { "cityData": "generate-city" } → then use {{cityData.taskOutput.field}} in config templates. ' + "Without 'inputs', built-in trigger/input/workflow/swarm/run context remains available, but upstream outputs do not. " + "Agent-task templates may interpolate trigger and declared upstream aliases. SECURITY: executable source for script/swarm-script nodes does not: " + "inline script source allows only input/workflow/swarm/run values, while named swarm-script source is not workflow-interpolated. " + `Pass dynamic trigger or upstream values through config.args (argv for inline scripts; the args object for swarm-script).
135986
136408
  ` + "- STRUCTURED OUTPUT: For agent-task nodes, put outputSchema inside 'config' to validate the agent's raw JSON output. " + `Node-level outputSchema validates the executor's return ({taskId, taskOutput}), which is different.
135987
136409
  ` + `- Agent-task config: { template, outputSchema?, agentId?, tags?, priority?, dir?, vcsRepo?, model? }.
135988
- ` + "- FOREACH NODE: type 'foreach' fans out one agent-task per item. Config: " + "{ over: <array or exact {{input}} token>, itemKey: <property name>, body: { type: 'agent-task', config: {...} } }. " + "The body config is interpolated once per item with {{item.*}} and {{index}}. Child steps use synthetic IDs " + "'<foreachNodeId>#<itemKey>'; the parent waits for every child and exposes one aggregate result to successors. " + `concurrency is not supported in v1; use definition-level onNodeFailure: 'continue' to aggregate failed children.
136410
+ ` + "- FOREACH NODE: type 'foreach' runs its body once per item. Config: " + "{ over: <array or exact {{input}} token>, itemKey: <property name>, body: { type: <any executor except foreach>, config: {...} }, " + "concurrency?: <integer >= 1, items in flight; unbounded when absent>, failurePolicy?: 'fail-fast' | 'collect-outcomes' }. " + "The body config is interpolated once per item with {{item.*}} and {{index}}. Child steps use synthetic IDs " + "'<foreachNodeId>#<itemKey>'; the parent waits for every child and exposes one aggregate result to successors. " + "failurePolicy defaults from onNodeFailure ('continue' = collect-outcomes, else fail-fast); fail-fast cancels queued items. " + `retry-workflow-run on a failed fan-out reruns only failed and cancelled items.
135989
136411
  ` + "- TRIGGER SCHEMA: Optional 'triggerSchema' is a JSON-Schema object that validates incoming trigger payloads. " + "Supported keywords: type, required, properties, enum, const, items (recursive into arrays). " + `Other JSON-Schema keywords (oneOf/anyOf/$ref/pattern/format/additionalProperties) are silently ignored.
135990
136412
  ` + "- WEBHOOK VERIFICATION: Webhook triggers use hmacSecret for all verification formats. " + "Omit verification for legacy HMAC-SHA256 over the raw body with fallback header scanning; " + "or set verification to { format: 'hmac-sha256', header }, { format: 'timestamped-hmac-sha256', header, toleranceSeconds? }, " + "{ format: 'token-equality', header }, or { format: 'standard-webhooks', toleranceSeconds? } " + "(standardwebhooks.com: webhook-id/webhook-timestamp/webhook-signature headers, hmacSecret is the whsec_ signing secret). Example: { type: 'webhook', hmacSecret: 'secret.SUPERAGENT_WEBHOOK_SECRET', " + `verification: { format: 'timestamped-hmac-sha256', header: 'X-Superagent-Signature', toleranceSeconds: 300 } }.
135991
136413
  ` + "- WAIT NODE: type 'wait' pauses a workflow for a duration or until a named workflowEventBus event arrives. " + "See runbooks/workflows.md#wait-nodes for config shapes, ordering caveats, and built-in event names.",
@@ -137032,4 +137454,4 @@ async function createServer(opts = {}) {
137032
137454
  return server;
137033
137455
  }
137034
137456
 
137035
- export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, taskModelPin, resumedTaskModelSelection, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, scopeFromAttachment, backingProviderId, transcribeAudioNotes, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, handleWebhookTrigger, verifyHmacSignature, WebhookError, snapshotAndUpdateWorkflow, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry2, initWorkflows2, dispatchScheduleTarget, calculateNextRun2, startScheduler2, stopScheduler2, runScheduleNow2, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError2, isRegistered2, isExtensionAgentId2, getExtensionBridgeToken2, resolveBridgeCallOrigin2, extensionIdForAgent2, runContext2, registerLoaded2, unregister2, listRegistered2, dispatchPre2, dispatchPost2, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, repointTrackerSyncBySwarmId, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, handleWorkItemCreated, handleWorkItemUpdated, handleWorkItemCommented, handleWorkItemDeleted, handleWorkItemRestored, initAzureDevOpsOutbound, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, insertProvisioningRuntime, markRuntimeTerminated, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, listRuntimeInstancesForPool, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2, handleNote, handlePipeline, isChatSdkEnabled, getChatSdkConfig, errorMessage, resolveAdapterApiUrl, trackBackground, TelegramBotApiError, callTelegramBotApi, isTrustedTeamsServiceUrl, isChatSdkStopping, startChatSdk, getChatInstance, isChatAdapterConfigured, getChatSdkHealth, stopChatSdk, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, isCookieSafePageId, extractPageSession, extractLegacyPageSession, extractAndVerifyCookie, pageSessionSetCookies, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, MCP_MAX_TOOL_INPUT_ELEMENTS, MCP_MAX_REQUEST_BODY_BYTES, userCtx, requestPrincipal, agentFirstPrincipal, rejectGuest, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, getPageEditCounter, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, MemoryKeyError, refreshLinks, indexMemoryContent, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, sessionAccessTopic, sessionPresenceRoot, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };
137457
+ export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, taskModelPin, resumedTaskModelSelection, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, scopeFromAttachment, backingProviderId, transcribeAudioNotes, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, handleWebhookTrigger, verifyHmacSignature, WebhookError, snapshotAndUpdateWorkflow, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry2, initWorkflows2, dispatchScheduleTarget, calculateNextRun2, startScheduler2, stopScheduler2, runScheduleNow2, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError2, isRegistered2, isExtensionAgentId2, getExtensionBridgeToken2, resolveBridgeCallOrigin2, extensionIdForAgent2, runContext2, registerLoaded2, unregister2, listRegistered2, dispatchPre2, dispatchPost2, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, repointTrackerSyncBySwarmId, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, handleWorkItemCreated, handleWorkItemUpdated, handleWorkItemCommented, handleWorkItemDeleted, handleWorkItemRestored, initAzureDevOpsOutbound, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, insertProvisioningRuntime, markRuntimeTerminated, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, listRuntimeInstancesForPool, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, isBitbucketEnabled, initBitbucket, verifyBitbucketWebhook, isDuplicateDelivery, markDeliveryProcessed, pullRequestEventOf, pullRequestCommentEventOf, handlePullRequestCreated2, handlePullRequestCommentCreated, handlePullRequestClosed, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2, handleNote, handlePipeline, isChatSdkEnabled, getChatSdkConfig, errorMessage, resolveAdapterApiUrl, trackBackground, TelegramBotApiError, callTelegramBotApi, isTrustedTeamsServiceUrl, isChatSdkStopping, startChatSdk, getChatInstance, isChatAdapterConfigured, getChatSdkHealth, stopChatSdk, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, isCookieSafePageId, extractPageSession, extractLegacyPageSession, extractAndVerifyCookie, pageSessionSetCookies, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, MCP_MAX_TOOL_INPUT_ELEMENTS, MCP_MAX_REQUEST_BODY_BYTES, userCtx, requestPrincipal, agentFirstPrincipal, rejectGuest, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, getPageEditCounter, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, MemoryKeyError, refreshLinks, indexMemoryContent, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, sessionAccessTopic, sessionPresenceRoot, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };