@desplega.ai/agent-swarm 2.4.5 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/README.md +4 -2
  2. package/dist/{acp-adapter-2wdkktv6.js → acp-adapter-11gp67nr.js} +8 -6
  3. package/dist/{actions-c40ebcm4.js → actions-8p2kze8j.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-0qp0a2gk.js} +3 -3
  7. package/dist/{assistant-sj1njh23.js → assistant-jedd3ktm.js} +24 -22
  8. package/dist/{azure-openai-responses-9dbmj346.js → azure-openai-responses-9kfwhmn7.js} +18 -13
  9. package/dist/{boot-reembed-qdkvxeem.js → boot-reembed-4xwq5tg0.js} +1 -1
  10. package/dist/{boot-reembed-b9c3az3c.js → boot-reembed-n4wq5dd2.js} +1 -1
  11. package/dist/{boot-scrub-sweep-m3wh8eks.js → boot-scrub-sweep-69h90xcq.js} +4 -4
  12. package/dist/{boot-seeds-j2273s54.js → boot-seeds-3vn0m9sg.js} +4 -4
  13. package/dist/{claude-adapter-m7q0a085.js → claude-adapter-221mvad5.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-8thjsk5e.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-dk44dxec.js → cli-0y6f0ckq.js} +1 -1
  20. package/dist/{cli-kpw04va0.js → cli-0z3vjrpm.js} +1 -1
  21. package/dist/{cli-94gwyg7m.js → cli-179xcyky.js} +9 -9
  22. package/dist/{cli-3r8samv3.js → cli-1f0gp9vz.js} +3 -2
  23. package/dist/{cli-4zfqgjc5.js → cli-1pr672hz.js} +2 -2
  24. package/dist/{cli-0bqteszy.js → cli-2nf3b08t.js} +328 -25
  25. package/dist/{cli-43x64hv3.js → cli-36j4jnk3.js} +4 -4
  26. package/dist/{cli-k8g16gz3.js → cli-3qv8naq8.js} +115 -119
  27. package/dist/cli-3zwye9sn.js +1193 -0
  28. package/dist/{cli-60cgh1rv.js → cli-459fk97x.js} +7 -7
  29. package/dist/{cli-v8fjakwf.js → cli-4w24f7z3.js} +1 -1
  30. package/dist/{cli-n72rg53p.js → cli-5kzk3472.js} +812 -418
  31. package/dist/{cli-h7gc0b4r.js → cli-5m84zd2k.js} +55 -18
  32. package/dist/{cli-j99azg3g.js → cli-5rvg1ddk.js} +5 -5
  33. package/dist/{cli-dvkmp9bt.js → cli-6ctwrf1z.js} +20 -10
  34. package/dist/{cli-848hxdwj.js → cli-6rg2jn2y.js} +2 -1
  35. package/dist/{cli-fv5hepyy.js → cli-7bwtc6yx.js} +3 -3
  36. package/dist/{cli-ms85309d.js → cli-7g40g8hq.js} +11 -11
  37. package/dist/{cli-xpa64rek.js → cli-92mqenkc.js} +2362 -159
  38. package/dist/{cli-018r4jq6.js → cli-9ce2xw98.js} +8 -8
  39. package/dist/{cli-1syn2xy1.js → cli-bgdtv62r.js} +32 -18
  40. package/dist/{cli-wxbn3yfx.js → cli-cz5nmdxt.js} +2 -2
  41. package/dist/{cli-wt645v7q.js → cli-dabehxhp.js} +1 -1
  42. package/dist/{cli-vfha21c9.js → cli-e5bxnjps.js} +2 -2
  43. package/dist/{cli-wt0jf9hm.js → cli-fcc5qe3f.js} +553 -193
  44. package/dist/{cli-ftc1g5tj.js → cli-fes51ya2.js} +3 -3
  45. package/dist/{cli-3a45zcgm.js → cli-ftmq4nvk.js} +2 -2
  46. package/dist/{cli-37j04k05.js → cli-fy1jyyym.js} +13 -13
  47. package/dist/{cli-s95dknxh.js → cli-g1cw7xtt.js} +1 -1
  48. package/dist/{cli-74c1wpm0.js → cli-gpv60278.js} +1 -1
  49. package/dist/{cli-pemywhfq.js → cli-ha9rmwgq.js} +2 -1
  50. package/dist/{cli-g35m2xwm.js → cli-j1eghqfm.js} +2 -2
  51. package/dist/{cli-qfxc84gh.js → cli-jpxsrxcb.js} +1 -1
  52. package/dist/{cli-ejs3m1sx.js → cli-kxpfx2xr.js} +1 -1
  53. package/dist/{cli-p14m2cnp.js → cli-mbfj11fq.js} +1 -1
  54. package/dist/{cli-pnp2j5zg.js → cli-mmhj8vd7.js} +2 -2
  55. package/dist/{cli-xf234ws8.js → cli-n4c8e3s5.js} +2 -0
  56. package/dist/{cli-f01h25yt.js → cli-n6kmqngw.js} +2 -2
  57. package/dist/{cli-v0yrfmdh.js → cli-nnvjb17s.js} +3 -3
  58. package/dist/{cli-1dmcq2eh.js → cli-nzfnt2gs.js} +1 -1
  59. package/dist/{cli-625tb7aq.js → cli-p859hcc8.js} +2 -2
  60. package/dist/{cli-smvcw9z5.js → cli-pasyvjmm.js} +1 -1
  61. package/dist/cli-pkaqk57w.js +128 -0
  62. package/dist/{cli-8nyhf7za.js → cli-qqzmjxkf.js} +129 -105
  63. package/dist/{cli-9yqgm9nd.js → cli-r25qpaxt.js} +161 -63
  64. package/dist/{cli-eww120g8.js → cli-rh5smt8t.js} +18 -4
  65. package/dist/{cli-qwkcwjdn.js → cli-rycdaj0a.js} +1 -1
  66. package/dist/{cli-a92r1127.js → cli-s4sntwt4.js} +2 -2
  67. package/dist/{cli-be2161h1.js → cli-segs7hx9.js} +6 -6
  68. package/dist/{cli-36ckw0wx.js → cli-stxdrqs2.js} +2 -2
  69. package/dist/{cli-z7d29rw9.js → cli-sy8f9705.js} +4 -4
  70. package/dist/{cli-1m17dc9d.js → cli-ta8bd7th.js} +2 -2
  71. package/dist/{cli-st8aw1m6.js → cli-we0ra057.js} +4 -4
  72. package/dist/{cli-7c9qs530.js → cli-x21dqn18.js} +5 -5
  73. package/dist/{cli-1sp861s4.js → cli-x6vf4sad.js} +11 -11
  74. package/dist/{cli-d2mb5s8a.js → cli-x77gen2p.js} +680 -440
  75. package/dist/{cli-tw4p90jb.js → cli-xawhpgc9.js} +5 -5
  76. package/dist/{cli-f0g3pgvf.js → cli-xd4eqtr2.js} +2 -2
  77. package/dist/{cli-1f3qzw6y.js → cli-xt768r5m.js} +2 -2
  78. package/dist/{cli-cxxe61f6.js → cli-y4x8ww6s.js} +2 -2
  79. package/dist/{cli-bnes4z6b.js → cli-y9jvxfhk.js} +3 -3
  80. package/dist/{cli-qwhy2qma.js → cli-z63a269p.js} +2 -2
  81. package/dist/{cli-sm8rses9.js → cli-zfdp01hn.js} +8 -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-tcg1q3jk.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-xfx4wd9x.js} +7 -5
  87. package/dist/{commands-t7rz9146.js → commands-ew83nj70.js} +2 -2
  88. package/dist/{controller-m2jasma5.js → controller-gnq1k1mf.js} +4 -4
  89. package/dist/{controllers-connect-9ftpex99.js → controllers-connect-tw1dan9r.js} +25 -23
  90. package/dist/{cursor-adapter-mjv79e4z.js → cursor-adapter-yq5xgfcg.js} +1 -1
  91. package/dist/{db-6sfrn9g3.js → db-7gbc53fd.js} +14 -2
  92. package/dist/{db-rn673r06.js → db-t86xrnes.js} +3 -3
  93. package/dist/{devin-adapter-zgqadvnm.js → devin-adapter-4ycy4vrf.js} +1 -1
  94. package/dist/{dispatcher-c155xz0p.js → dispatcher-64bdyhps.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-e9nw24zv.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-v82srhrx.js} +9 -7
  106. package/dist/handlers-c9ajzhbn.js +41 -0
  107. package/dist/{heartbeat-dyg4npkp.js → heartbeat-2vqs1319.js} +25 -23
  108. package/dist/{hook-x26b31bg.js → hook-01nk13wx.js} +7 -5
  109. package/dist/{hook-drspbwpe.js → hook-jzpheegg.js} +9 -7
  110. package/dist/{http-pk972xyw.js → http-fc1k6ec8.js} +544 -76
  111. package/dist/index-07ef7nkm.js +42 -0
  112. package/dist/{index-g6tbb6ve.js → index-31ceyf42.js} +1 -1
  113. package/dist/index-7yts8n9s.js +43 -0
  114. package/dist/index-q3t40ryv.js +46 -0
  115. package/dist/{index-arytgj5q.js → index-sepja052.js} +1 -1
  116. package/dist/{index-jwxkkex2.js → index-zdycv3ja.js} +13 -11
  117. package/dist/{index-g216q6jr.js → index-zsyx51ap.js} +1 -4
  118. package/dist/{keepalive-7yrng7px.js → keepalive-5nh2rhmr.js} +4 -4
  119. package/dist/lead-aayq64jn.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-hjhzdt3k.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-y3n1knmd.js} +3 -3
  125. package/dist/{onboard-0a9y5yrc.js → onboard-1zq3m7db.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-h9yyza47.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-nevhat8h.js} +3 -3
  136. package/dist/{rbac-roles-nxh5ahwk.js → rbac-roles-4y6ngvzq.js} +1 -1
  137. package/dist/{rbac-roles-hey3yv9d.js → rbac-roles-exbg8xb6.js} +2 -2
  138. package/dist/{render-v2-rr3p2atg.js → render-v2-cfsh13z3.js} +3 -3
  139. package/dist/{resume-2efkf1s1.js → resume-5s2t0dbs.js} +10 -8
  140. package/dist/{runtime-xe3aqy4x.js → runtime-bt5pkpm1.js} +1 -1
  141. package/dist/{session-access-s2mttxpw.js → session-access-dnbyp3cn.js} +6 -4
  142. package/dist/{setup-vypma5yt.js → setup-1wj1y77j.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-7mg6216g.js} +25 -23
  146. package/dist/worker-nwb789mg.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/handlers.ts +5 -5
  174. package/src/http/assets.ts +14 -2
  175. package/src/http/core.ts +12 -0
  176. package/src/http/index.ts +4 -0
  177. package/src/http/onboarding.ts +1 -0
  178. package/src/http/sessions.ts +366 -12
  179. package/src/http/skills.ts +48 -1
  180. package/src/http/tasks.ts +1 -1
  181. package/src/http/users.ts +1 -0
  182. package/src/http/webhooks.ts +141 -0
  183. package/src/integrations/chat-sdk/adapters.ts +19 -3
  184. package/src/integrations/chat-sdk/facts.ts +30 -12
  185. package/src/integrations/chat-sdk/outbound.ts +38 -1
  186. package/src/providers/acp-targets.ts +1 -1
  187. package/src/providers/amp-adapter.ts +1 -1
  188. package/src/providers/pi-mono-adapter.ts +5 -53
  189. package/src/scripts-runtime/types/swarm-extension.d.ts +6 -4
  190. package/src/slack/handlers.test.ts +158 -0
  191. package/src/slack/handlers.ts +19 -28
  192. package/src/tasks/context-key.ts +61 -1
  193. package/src/tests/bitbucket-auth.test.ts +156 -0
  194. package/src/tests/bitbucket-handlers.test.ts +425 -0
  195. package/src/tests/bitbucket-webhook.test.ts +220 -0
  196. package/src/tests/chat-sdk-inbound.test.ts +39 -0
  197. package/src/tests/chat-sdk-telegram-markdown.test.ts +92 -0
  198. package/src/tests/context-key.test.ts +50 -0
  199. package/src/tests/core-auth.test.ts +5 -0
  200. package/src/tests/db-task-read-contract.test.ts +7 -0
  201. package/src/tests/db-task-write-contract.test.ts +6 -0
  202. package/src/tests/docs-index-footprint.test.js +3 -3
  203. package/src/tests/fixtures/bitbucket/pullrequest-comment-created-inline.json +174 -0
  204. package/src/tests/fixtures/bitbucket/pullrequest-comment-created.json +170 -0
  205. package/src/tests/fixtures/bitbucket/pullrequest-created-mention.json +132 -0
  206. package/src/tests/fixtures/bitbucket/pullrequest-created-reviewer.json +140 -0
  207. package/src/tests/fixtures/bitbucket/pullrequest-fulfilled.json +134 -0
  208. package/src/tests/fixtures/bitbucket/pullrequest-rejected.json +133 -0
  209. package/src/tests/generate-mcp-docs.test.ts +101 -0
  210. package/src/tests/gitlab-handlers.test.ts +3 -3
  211. package/src/tests/gitlab-vcs-db.test.ts +4 -4
  212. package/src/tests/integration-disable-flags.test.ts +36 -0
  213. package/src/tests/mcp-tools.test.ts +1 -1
  214. package/src/tests/onboarding.test.ts +12 -0
  215. package/src/tests/pi-codemode.test.ts +8 -2
  216. package/src/tests/preload-env.test.ts +57 -0
  217. package/src/tests/preload.ts +21 -0
  218. package/src/tests/prompt-template-remaining.test.ts +38 -0
  219. package/src/tests/run-root-coverage.test.ts +39 -0
  220. package/src/tests/runner-bitbucket-vcs.test.ts +191 -0
  221. package/src/tests/runner-skills-refresh.test.ts +58 -0
  222. package/src/tests/secret-scrubber.test.ts +15 -0
  223. package/src/tests/sessions-move.test.ts +576 -0
  224. package/src/tests/sessions-tree.test.ts +493 -0
  225. package/src/tests/skill-files-http.test.ts +50 -0
  226. package/src/tests/skills-bundle.test.ts +99 -0
  227. package/src/tests/swarm-config-export-to-env.test.ts +2 -1
  228. package/src/tests/vcs-bitbucket.test.ts +91 -0
  229. package/src/tests/vcs-provider-isolation.test.ts +123 -0
  230. package/src/tests/vcs-provider.test.ts +16 -1
  231. package/src/tests/vcs-tracking.test.ts +3 -3
  232. package/src/tests/workflow-foreach-bodies.test.ts +637 -0
  233. package/src/tests/workflow-foreach-concurrency.test.ts +342 -0
  234. package/src/tests/workflow-foreach-retry.test.ts +537 -0
  235. package/src/tests/workflow-foreach.test.ts +44 -23
  236. package/src/tests/workflow-step-claims.test.ts +6 -6
  237. package/src/tests/workflow-tla-races.test.ts +2 -2
  238. package/src/tools/script-delete.ts +1 -1
  239. package/src/tools/workflows/create-workflow.ts +5 -3
  240. package/src/types.ts +3 -2
  241. package/src/utils/config-env-export.ts +1 -0
  242. package/src/utils/secret-scrubber.ts +4 -0
  243. package/src/utils/skills-refresh.ts +83 -43
  244. package/src/vcs/bitbucket.ts +58 -0
  245. package/src/vcs/index.ts +2 -0
  246. package/src/vcs/types.ts +2 -2
  247. package/src/workflows/approval-resolution.ts +4 -1
  248. package/src/workflows/checkpoint.ts +9 -1
  249. package/src/workflows/constants.ts +3 -0
  250. package/src/workflows/definition.ts +48 -17
  251. package/src/workflows/engine.ts +25 -15
  252. package/src/workflows/executors/foreach.ts +45 -99
  253. package/src/workflows/foreach-body.ts +146 -0
  254. package/src/workflows/foreach-driver.ts +552 -0
  255. package/src/workflows/foreach-join.ts +206 -7
  256. package/src/workflows/node-timeout.ts +21 -0
  257. package/src/workflows/recovery.ts +68 -3
  258. package/src/workflows/resume.ts +221 -43
  259. package/src/workflows/retry-poller.ts +39 -24
  260. package/src/workflows/step-input.ts +59 -0
  261. package/src/workflows/task-step-routing.ts +114 -56
  262. package/templates/skills/slack-interaction/content.md +5 -0
  263. package/templates/skills/work-on-task/SKILL.md +1 -1
  264. package/templates/skills/work-on-task/content.md +1 -1
  265. package/dist/cli-9hstj09h.js +0 -2657
  266. package/dist/cli-yw91rnmw.js +0 -13
  267. package/dist/handlers-7gw64dxw.js +0 -39
  268. package/dist/index-bgdyvcnv.js +0 -40
  269. package/dist/index-gabbcdn2.js +0 -43
  270. package/dist/index-tfb26zhy.js +0 -41
  271. package/dist/lead-7e02z839.js +0 -77
  272. 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-fcc5qe3f.js";
338
340
  import {
339
341
  getUserGrant2,
340
342
  init_rbac_roles
341
- } from "./cli-kpw04va0.js";
343
+ } from "./cli-0z3vjrpm.js";
342
344
  import {
343
345
  ensurePricingSeeded2,
344
346
  ensureRbacSeeded2,
345
347
  ensureModelProfilesSeeded2
346
- } from "./cli-43x64hv3.js";
348
+ } from "./cli-36j4jnk3.js";
347
349
  import {
348
350
  loadModelsDevCache
349
- } from "./cli-dk44dxec.js";
351
+ } from "./cli-0y6f0ckq.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-y9jvxfhk.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-92mqenkc.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-we0ra057.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-s4sntwt4.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-fy1jyyym.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-ftmq4nvk.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-3zwye9sn.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-9ce2xw98.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-5rvg1ddk.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-xt768r5m.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-179xcyky.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-0qp0a2gk.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-64bdyhps.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,46 @@ 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
30915
  var GITLAB_BOT_NAME = process.env.GITLAB_BOT_NAME ?? "agent-swarm-bot";
30562
30916
  function resetGitLab() {
30563
- initialized4 = false;
30564
- webhookSecret4 = null;
30565
- apiToken2 = null;
30917
+ initialized5 = false;
30918
+ webhookSecret5 = null;
30919
+ apiToken3 = null;
30566
30920
  gitlabUrl = "https://gitlab.com";
30567
30921
  }
30568
30922
  // src/gitlab/handlers.ts
@@ -30572,7 +30926,7 @@ init_resolver();
30572
30926
  init_context_key();
30573
30927
 
30574
30928
  // src/gitlab/reactions.ts
30575
- function headers3() {
30929
+ function headers4() {
30576
30930
  const token = getGitLabToken();
30577
30931
  if (!token)
30578
30932
  throw new Error("[GitLab] No API token configured");
@@ -30593,7 +30947,7 @@ async function addGitLabReaction(project, entityType, iid, emojiName) {
30593
30947
  try {
30594
30948
  const resp = await fetch(url, {
30595
30949
  method: "POST",
30596
- headers: headers3(),
30950
+ headers: headers4(),
30597
30951
  body: JSON.stringify({ name: emojiName })
30598
30952
  });
30599
30953
  if (!resp.ok) {
@@ -30609,7 +30963,7 @@ async function addGitLabNoteReaction(project, entityType, iid, noteId, emojiName
30609
30963
  try {
30610
30964
  const resp = await fetch(url, {
30611
30965
  method: "POST",
30612
- headers: headers3(),
30966
+ headers: headers4(),
30613
30967
  body: JSON.stringify({ name: emojiName })
30614
30968
  });
30615
30969
  if (!resp.ok) {
@@ -30733,33 +31087,33 @@ The CI pipeline has failed. Please investigate and fix the issues.{{@template[co
30733
31087
  });
30734
31088
 
30735
31089
  // src/gitlab/handlers.ts
30736
- var processedEvents4 = new Map;
30737
- var DEDUP_TTL_MS2 = 60000;
30738
- function isDuplicate4(key) {
31090
+ var processedEvents5 = new Map;
31091
+ var DEDUP_TTL_MS3 = 60000;
31092
+ function isDuplicate5(key) {
30739
31093
  const now = Date.now();
30740
- for (const [k, ts] of processedEvents4) {
30741
- if (now - ts > DEDUP_TTL_MS2)
30742
- processedEvents4.delete(k);
31094
+ for (const [k, ts] of processedEvents5) {
31095
+ if (now - ts > DEDUP_TTL_MS3)
31096
+ processedEvents5.delete(k);
30743
31097
  }
30744
- if (processedEvents4.has(key))
31098
+ if (processedEvents5.has(key))
30745
31099
  return true;
30746
- processedEvents4.set(key, now);
31100
+ processedEvents5.set(key, now);
30747
31101
  return false;
30748
31102
  }
30749
- function detectMention3(text) {
31103
+ function detectMention4(text) {
30750
31104
  if (!text)
30751
31105
  return false;
30752
31106
  return new RegExp(`@${GITLAB_BOT_NAME}\\b`, "i").test(text);
30753
31107
  }
30754
- function extractMentionContext3(text) {
31108
+ function extractMentionContext4(text) {
30755
31109
  return text.replace(new RegExp(`@${GITLAB_BOT_NAME}\\b`, "gi"), "").trim();
30756
31110
  }
30757
- async function findLeadAgent4() {
31111
+ async function findLeadAgent5() {
30758
31112
  const agents = await getAllAgents2();
30759
31113
  return agents.find((a) => a.role === "lead" && a.status === "idle") ?? agents.find((a) => a.role === "lead") ?? null;
30760
31114
  }
30761
- var UNMAPPED_NAMESPACE3 = "integration:unmapped:gitlab";
30762
- var UNMAPPED_TTL_MS3 = 30 * 24 * 60 * 60 * 1000;
31115
+ var UNMAPPED_NAMESPACE4 = "integration:unmapped:gitlab";
31116
+ var UNMAPPED_TTL_MS4 = 30 * 24 * 60 * 60 * 1000;
30763
31117
  var GITLAB_WEBHOOK_ACTOR = { kind: "system", id: "webhook:gitlab" };
30764
31118
  async function resolveGitLabSender(user, sampleEventType, sampleContext) {
30765
31119
  const existing = await findUserByExternalId("gitlab", user.username);
@@ -30772,7 +31126,7 @@ async function resolveGitLabSender(user, sampleEventType, sampleContext) {
30772
31126
  return linked.id;
30773
31127
  }
30774
31128
  await upsertKv2({
30775
- namespace: UNMAPPED_NAMESPACE3,
31129
+ namespace: UNMAPPED_NAMESPACE4,
30776
31130
  key: `${user.username}:meta`,
30777
31131
  value: {
30778
31132
  lastSeenAt: new Date().toISOString(),
@@ -30780,9 +31134,9 @@ async function resolveGitLabSender(user, sampleEventType, sampleContext) {
30780
31134
  sampleContext: sampleContext.slice(0, 100)
30781
31135
  },
30782
31136
  valueType: "json",
30783
- expiresAt: Date.now() + UNMAPPED_TTL_MS3
31137
+ expiresAt: Date.now() + UNMAPPED_TTL_MS4
30784
31138
  });
30785
- await incrKv2(UNMAPPED_NAMESPACE3, `${user.username}:count`, 1);
31139
+ await incrKv2(UNMAPPED_NAMESPACE4, `${user.username}:count`, 1);
30786
31140
  return;
30787
31141
  }
30788
31142
  async function renderGitLabIdentity(username) {
@@ -30795,19 +31149,19 @@ async function handleMergeRequest(event) {
30795
31149
  const requestedByUserId = await resolveGitLabSender(user, "merge_request", `MR !${mr.iid}: ${mr.title}`);
30796
31150
  console.log(`[GitLab] MR #${mr.iid} ${action} by ${user.username} in ${repo}`);
30797
31151
  const dedupKey = `gitlab-mr-${repo}-${mr.iid}-${action}-${user.username}`;
30798
- if (isDuplicate4(dedupKey)) {
31152
+ if (isDuplicate5(dedupKey)) {
30799
31153
  console.log(`[GitLab] Skipping duplicate MR event`);
30800
31154
  return { created: false };
30801
31155
  }
30802
- const lead = await findLeadAgent4();
31156
+ const lead = await findLeadAgent5();
30803
31157
  switch (action) {
30804
31158
  case "open": {
30805
- const hasMention = detectMention3(mr.description);
31159
+ const hasMention = detectMention4(mr.description);
30806
31160
  if (!hasMention) {
30807
31161
  console.log(`[GitLab] MR opened without bot mention, skipping`);
30808
31162
  return { created: false };
30809
31163
  }
30810
- const context = mr.description ? extractMentionContext3(mr.description) : "";
31164
+ const context = mr.description ? extractMentionContext4(mr.description) : "";
30811
31165
  const contextSection = context ? `Context: ${context}
30812
31166
 
30813
31167
  ` : "";
@@ -30851,7 +31205,7 @@ async function handleMergeRequest(event) {
30851
31205
  }
30852
31206
  case "close":
30853
31207
  case "merge": {
30854
- const existingTask = await findTaskByVcs2(repo, mr.iid);
31208
+ const existingTask = await findTaskByVcs2(repo, mr.iid, "gitlab");
30855
31209
  if (existingTask) {
30856
31210
  const reason = action === "merge" ? "MR was merged" : "MR was closed";
30857
31211
  console.log(`[GitLab] Cancelling task ${existingTask.id} — ${reason}`);
@@ -30860,7 +31214,7 @@ async function handleMergeRequest(event) {
30860
31214
  return { created: false };
30861
31215
  }
30862
31216
  case "update": {
30863
- const task = await findTaskByVcs2(repo, mr.iid);
31217
+ const task = await findTaskByVcs2(repo, mr.iid, "gitlab");
30864
31218
  if (task) {
30865
31219
  console.log(`[GitLab] MR #${mr.iid} updated, active task exists: ${task.id}`);
30866
31220
  return { created: false };
@@ -30879,13 +31233,13 @@ async function handleIssue2(event) {
30879
31233
  const requestedByUserId = await resolveGitLabSender(user, "issue", `Issue #${issue.iid}: ${issue.title}`);
30880
31234
  console.log(`[GitLab] Issue #${issue.iid} ${action} by ${user.username} in ${repo}`);
30881
31235
  const dedupKey = `gitlab-issue-${repo}-${issue.iid}-${action}-${user.username}`;
30882
- if (isDuplicate4(dedupKey)) {
31236
+ if (isDuplicate5(dedupKey)) {
30883
31237
  return { created: false };
30884
31238
  }
30885
- const lead = await findLeadAgent4();
31239
+ const lead = await findLeadAgent5();
30886
31240
  switch (action) {
30887
31241
  case "open": {
30888
- const hasMention = detectMention3(issue.description);
31242
+ const hasMention = detectMention4(issue.description);
30889
31243
  if (!hasMention) {
30890
31244
  const isBotAssigned = event.assignees?.some((a) => a.username.toLowerCase() === GITLAB_BOT_NAME.toLowerCase());
30891
31245
  if (!isBotAssigned) {
@@ -30893,7 +31247,7 @@ async function handleIssue2(event) {
30893
31247
  return { created: false };
30894
31248
  }
30895
31249
  }
30896
- const context = issue.description ? extractMentionContext3(issue.description) : "";
31250
+ const context = issue.description ? extractMentionContext4(issue.description) : "";
30897
31251
  const contextSection = context ? `Context: ${context}
30898
31252
 
30899
31253
  ` : "";
@@ -30934,7 +31288,7 @@ async function handleIssue2(event) {
30934
31288
  return { created: true, taskId: task.id };
30935
31289
  }
30936
31290
  case "close": {
30937
- const existingTask = await findTaskByVcs2(repo, issue.iid);
31291
+ const existingTask = await findTaskByVcs2(repo, issue.iid, "gitlab");
30938
31292
  if (existingTask) {
30939
31293
  console.log(`[GitLab] Cancelling task ${existingTask.id} — issue closed`);
30940
31294
  await failTask2(existingTask.id, "Issue was closed");
@@ -30949,16 +31303,16 @@ async function handleNote(event) {
30949
31303
  const { user, project, object_attributes: note } = event;
30950
31304
  const repo = project.path_with_namespace;
30951
31305
  const requestedByUserId = await resolveGitLabSender(user, "note", note.note);
30952
- if (!detectMention3(note.note)) {
31306
+ if (!detectMention4(note.note)) {
30953
31307
  return { created: false };
30954
31308
  }
30955
31309
  console.log(`[GitLab] Note by ${user.username} in ${repo} (${note.noteable_type})`);
30956
31310
  const dedupKey = `gitlab-note-${note.id}`;
30957
- if (isDuplicate4(dedupKey)) {
31311
+ if (isDuplicate5(dedupKey)) {
30958
31312
  return { created: false };
30959
31313
  }
30960
- const lead = await findLeadAgent4();
30961
- const context = extractMentionContext3(note.note);
31314
+ const lead = await findLeadAgent5();
31315
+ const context = extractMentionContext4(note.note);
30962
31316
  let targetNumber;
30963
31317
  let targetUrl;
30964
31318
  let eventType;
@@ -30977,7 +31331,7 @@ async function handleNote(event) {
30977
31331
  console.log(`[GitLab] Ignoring note on ${note.noteable_type}`);
30978
31332
  return { created: false };
30979
31333
  }
30980
- const existingTask = targetNumber ? await findTaskByVcs2(repo, targetNumber) : null;
31334
+ const existingTask = targetNumber ? await findTaskByVcs2(repo, targetNumber, "gitlab") : null;
30981
31335
  const existingTaskNote = existingTask ? `
30982
31336
 
30983
31337
  _Note: There's an active task (${existingTask.id}) for this ${entityLabel}._` : "";
@@ -31032,14 +31386,14 @@ async function handlePipeline(event) {
31032
31386
  }
31033
31387
  const mrIid = event.merge_request.iid;
31034
31388
  const dedupKey = `gitlab-pipeline-${pipeline.id}`;
31035
- if (isDuplicate4(dedupKey)) {
31389
+ if (isDuplicate5(dedupKey)) {
31036
31390
  return { created: false };
31037
31391
  }
31038
- const existingTask = await findTaskByVcs2(repo, mrIid);
31392
+ const existingTask = await findTaskByVcs2(repo, mrIid, "gitlab");
31039
31393
  if (!existingTask) {
31040
31394
  return { created: false };
31041
31395
  }
31042
- const lead = await findLeadAgent4();
31396
+ const lead = await findLeadAgent5();
31043
31397
  const pipelineResult = resolveTemplate("gitlab.pipeline.failed", {
31044
31398
  pipeline_id: pipeline.id,
31045
31399
  mr_iid: mrIid,
@@ -31243,6 +31597,71 @@ function readApiUrlOverrides() {
31243
31597
  }
31244
31598
  }
31245
31599
 
31600
+ // src/integrations/chat-sdk/facts.ts
31601
+ var SNIPPET_MAX = 80;
31602
+ function snippet2(text) {
31603
+ const flat = text?.replace(/\s+/g, " ").trim();
31604
+ if (!flat)
31605
+ return;
31606
+ return flat.length > SNIPPET_MAX ? `${flat.slice(0, SNIPPET_MAX)}...` : flat;
31607
+ }
31608
+ function personLabel(name, username, fallback) {
31609
+ if (name && username && name !== username)
31610
+ return `${name} (@${username})`;
31611
+ if (username)
31612
+ return `@${username}`;
31613
+ return name || fallback;
31614
+ }
31615
+ function replyIsTopicRoot(raw) {
31616
+ const reply = raw.reply_to_message;
31617
+ return reply !== undefined && (reply.forum_topic_created !== undefined || raw.is_topic_message === true && reply.message_id === raw.message_thread_id);
31618
+ }
31619
+ function isTelegramReplyToBot(raw, botUserId) {
31620
+ const fromId = raw.reply_to_message?.from?.id;
31621
+ return !replyIsTopicRoot(raw) && fromId !== undefined && botUserId !== undefined && String(fromId) === botUserId;
31622
+ }
31623
+ function telegramFacts(raw, message, botUserId) {
31624
+ const reply = raw.reply_to_message;
31625
+ const topicRoot = replyIsTopicRoot(raw);
31626
+ const realReply = reply && !topicRoot ? reply : undefined;
31627
+ const topicName = topicRoot ? reply?.forum_topic_created?.name : undefined;
31628
+ const name = [raw.from?.first_name, raw.from?.last_name].filter(Boolean).join(" ").trim();
31629
+ return {
31630
+ chatType: raw.chat?.type,
31631
+ isForum: raw.chat?.is_forum === true ? true : undefined,
31632
+ title: raw.chat?.title,
31633
+ topic: raw.is_topic_message === true && raw.message_thread_id !== undefined ? topicName ? `"${topicName}"` : `#${raw.message_thread_id}` : undefined,
31634
+ from: personLabel(name || undefined, raw.from?.username, message.author.userId),
31635
+ replyToBot: isTelegramReplyToBot(raw, botUserId),
31636
+ replyToSnippet: snippet2(realReply?.text ?? realReply?.caption)
31637
+ };
31638
+ }
31639
+ function readChatMessageFacts(thread, message) {
31640
+ const raw = message.raw;
31641
+ if (thread.adapter.name === "telegram" && raw && typeof raw === "object") {
31642
+ return telegramFacts(raw, message, thread.adapter.botUserId);
31643
+ }
31644
+ const { fullName, userName, userId } = message.author;
31645
+ return {
31646
+ chatType: thread.isDM ? "dm" : undefined,
31647
+ from: personLabel(fullName || undefined, userName || undefined, userId),
31648
+ replyToBot: message.replyTo?.author.isMe === true,
31649
+ replyToSnippet: snippet2(message.replyTo?.text)
31650
+ };
31651
+ }
31652
+ function formatChatHeaderFacts(adapter, facts, addressed) {
31653
+ const oneLine = (text) => text.replace(/\s+/g, " ").trim();
31654
+ const parts = [adapter];
31655
+ if (facts.chatType)
31656
+ parts.push(facts.title ? `${facts.chatType} "${oneLine(facts.title)}"` : facts.chatType);
31657
+ if (facts.isForum)
31658
+ parts.push(facts.topic ? `forum topic ${oneLine(facts.topic)}` : "forum");
31659
+ parts.push(`from: ${oneLine(facts.from)}`, `addressed: ${addressed}`);
31660
+ if (facts.replyToSnippet)
31661
+ parts.push(`reply-to: "${facts.replyToSnippet}"`);
31662
+ return parts.join(" · ");
31663
+ }
31664
+
31246
31665
  // src/integrations/chat-sdk/logger.ts
31247
31666
  init_secret_scrubber();
31248
31667
  var MAX_ISSUE_CHARS = 300;
@@ -31334,8 +31753,14 @@ async function loadAdapter(name, config, logger) {
31334
31753
  const base = { ...config, apiUrl, logger };
31335
31754
  switch (name) {
31336
31755
  case "telegram": {
31337
- const { createTelegramAdapter } = await import("./index-g216q6jr.js");
31338
- return createTelegramAdapter({
31756
+ const { TelegramAdapter } = await import("./index-zsyx51ap.js");
31757
+
31758
+ class SwarmTelegramAdapter extends TelegramAdapter {
31759
+ isBotMentioned(message, text) {
31760
+ return super.isBotMentioned(message, text) || String(message.from?.id) !== this.botUserId && isTelegramReplyToBot(message, this.botUserId);
31761
+ }
31762
+ }
31763
+ return new SwarmTelegramAdapter({
31339
31764
  ...base,
31340
31765
  allowUnverifiedWebhooks: false,
31341
31766
  mentionOnReply: true
@@ -32383,63 +32808,6 @@ async function attachChatFilesToTask(taskId, fetched) {
32383
32808
  return unattached;
32384
32809
  }
32385
32810
 
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
32811
  // src/integrations/chat-sdk/outbound.ts
32444
32812
  init_secret_scrubber();
32445
32813
  init_event_bus();
@@ -32515,11 +32883,32 @@ class ChatFileTooLargeError extends Error {
32515
32883
  this.name = "ChatFileTooLargeError";
32516
32884
  }
32517
32885
  }
32886
+ var FENCE_LINE = /^ {0,3}(`{3,}|~{3,})/;
32887
+ var NON_HEADING_HASH = /^( {0,3}(?:>[ \t]?)*[ \t]*(?:(?:[-*+]|\d{1,9}[.)])[ \t]+(?:\[[ xX]\][ \t]+)?)?)(#{7,}|#{1,6}(?=[^\s#]))/;
32888
+ function escapeTelegramHashLines(markdown) {
32889
+ let fence;
32890
+ return markdown.split(`
32891
+ `).map((line) => {
32892
+ const marker = FENCE_LINE.exec(line)?.[1];
32893
+ if (fence) {
32894
+ if (marker && marker[0] === fence[0] && marker.length >= fence.length)
32895
+ fence = undefined;
32896
+ return line;
32897
+ }
32898
+ if (marker) {
32899
+ fence = marker;
32900
+ return line;
32901
+ }
32902
+ return line.replace(NON_HEADING_HASH, "$1\\$2");
32903
+ }).join(`
32904
+ `);
32905
+ }
32518
32906
  async function postChunks(adapter, target, text) {
32519
32907
  const messageIds = [];
32520
32908
  let threadId;
32521
32909
  for (const chunk of splitChatMessage(text, chatMessageLimit(adapter))) {
32522
- const sent = await target.post({ markdown: chunk });
32910
+ const markdown = adapter === "telegram" ? escapeTelegramHashLines(chunk) : chunk;
32911
+ const sent = await target.post({ markdown });
32523
32912
  messageIds.push(sent.id);
32524
32913
  threadId ??= sent.threadId;
32525
32914
  }
@@ -34251,7 +34640,7 @@ async function resolveBotAccountId() {
34251
34640
  function resetBotAccountIdCache() {
34252
34641
  setCachedBotAccountId(null);
34253
34642
  }
34254
- async function findLeadAgent5() {
34643
+ async function findLeadAgent6() {
34255
34644
  const agents = await getAllAgents2();
34256
34645
  const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
34257
34646
  if (onlineLead)
@@ -34455,7 +34844,7 @@ async function handleIssueDeleteEvent(event) {
34455
34844
  }
34456
34845
  }
34457
34846
  async function createInitialJiraTask(input) {
34458
- const lead = await findLeadAgent5();
34847
+ const lead = await findLeadAgent6();
34459
34848
  const descriptionSection = input.descriptionText ? `
34460
34849
  Description:
34461
34850
  ${input.descriptionText}
@@ -34493,7 +34882,7 @@ ${input.descriptionText}
34493
34882
  console.log(`[Jira Sync] Created ${action} task ${task.id} for ${input.issueKey} -> ${lead?.name ?? "unassigned"}`);
34494
34883
  }
34495
34884
  async function createCommentMentionTask(input) {
34496
- const lead = await findLeadAgent5();
34885
+ const lead = await findLeadAgent6();
34497
34886
  const descriptionSection = input.descriptionText ? `
34498
34887
  Description:
34499
34888
  ${input.descriptionText}
@@ -34553,7 +34942,7 @@ async function notifySlack(text) {
34553
34942
  return;
34554
34943
  }
34555
34944
  try {
34556
- const { getSlackApp } = await import("./app-353vre8g.js");
34945
+ const { getSlackApp } = await import("./app-0qp0a2gk.js");
34557
34946
  const app = getSlackApp();
34558
34947
  if (!app) {
34559
34948
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -34624,7 +35013,7 @@ async function deleteJiraWebhook(webhookId) {
34624
35013
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
34625
35014
  }
34626
35015
  async function overwriteWebhookIds(next) {
34627
- const { getDbClient } = await import("./db-6sfrn9g3.js");
35016
+ const { getDbClient } = await import("./db-7gbc53fd.js");
34628
35017
  await getDbClient().transaction(async (tx) => {
34629
35018
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
34630
35019
  if (!row) {
@@ -34731,7 +35120,7 @@ function stopJiraWebhookKeepalive() {
34731
35120
  }
34732
35121
 
34733
35122
  // src/jira/app.ts
34734
- var initialized5 = false;
35123
+ var initialized6 = false;
34735
35124
  function isJiraEnabled() {
34736
35125
  if (isEnvFlagEnabled("JIRA_DISABLE", false))
34737
35126
  return false;
@@ -34743,12 +35132,12 @@ function resetJira() {
34743
35132
  resetBotAccountIdCache();
34744
35133
  teardownJiraOutboundSync();
34745
35134
  stopJiraWebhookKeepalive();
34746
- initialized5 = false;
35135
+ initialized6 = false;
34747
35136
  }
34748
35137
  async function initJira() {
34749
- if (initialized5)
35138
+ if (initialized6)
34750
35139
  return isJiraEnabled();
34751
- initialized5 = true;
35140
+ initialized6 = true;
34752
35141
  if (!isJiraEnabled()) {
34753
35142
  console.log("[Jira] Integration disabled or JIRA_CLIENT_ID not set");
34754
35143
  return false;
@@ -34805,7 +35194,7 @@ function synthesizeDeliveryId(body, rawBody) {
34805
35194
  const hash = createHash2("sha256").update(rawBody).digest("hex").slice(0, 16);
34806
35195
  return `${event}:${ts}:${entityId}:${hash}`;
34807
35196
  }
34808
- async function isDuplicateDelivery(deliveryId) {
35197
+ async function isDuplicateDelivery2(deliveryId) {
34809
35198
  return await hasTrackerDelivery("jira", deliveryId);
34810
35199
  }
34811
35200
  async function markDelivery(externalId, deliveryId) {
@@ -34828,7 +35217,7 @@ async function handleJiraWebhook(pathToken, rawBody) {
34828
35217
  return { status: 200, body: { status: "ignored", reason: "invalid-json" } };
34829
35218
  }
34830
35219
  const deliveryId = synthesizeDeliveryId(parsed, rawBody);
34831
- if (await isDuplicateDelivery(deliveryId)) {
35220
+ if (await isDuplicateDelivery2(deliveryId)) {
34832
35221
  return { status: 200, body: { status: "duplicate" } };
34833
35222
  }
34834
35223
  const event = String(parsed.webhookEvent ?? "");
@@ -106647,15 +107036,15 @@ async function _fetchIssueGatingInfo(issueId) {
106647
107036
  const labelNames = (json.data?.issue?.labels?.nodes ?? []).map((n) => n?.name ?? "").filter((n) => n.length > 0);
106648
107037
  return { stateType, labelNames };
106649
107038
  }
106650
- async function findLeadAgent6() {
107039
+ async function findLeadAgent7() {
106651
107040
  const agents = await getAllAgents2();
106652
107041
  const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
106653
107042
  if (onlineLead)
106654
107043
  return onlineLead;
106655
107044
  return agents.find((a) => a.isLead) ?? null;
106656
107045
  }
106657
- var UNMAPPED_NAMESPACE4 = "integration:unmapped:linear";
106658
- var UNMAPPED_TTL_MS4 = 30 * 24 * 60 * 60 * 1000;
107046
+ var UNMAPPED_NAMESPACE5 = "integration:unmapped:linear";
107047
+ var UNMAPPED_TTL_MS5 = 30 * 24 * 60 * 60 * 1000;
106659
107048
  var LINEAR_WEBHOOK_ACTOR = { kind: "system", id: "webhook:linear" };
106660
107049
  var APP_USER_ID_NAMESPACE = "integration:linear:bot-app-user-id";
106661
107050
  async function getStoredAppUserId(workspaceId) {
@@ -106686,7 +107075,7 @@ async function resolveLinearActor(linearUserId, email, name, workspaceId, sample
106686
107075
  return linked.id;
106687
107076
  }
106688
107077
  await upsertKv2({
106689
- namespace: UNMAPPED_NAMESPACE4,
107078
+ namespace: UNMAPPED_NAMESPACE5,
106690
107079
  key: `${linearUserId}:meta`,
106691
107080
  value: {
106692
107081
  lastSeenAt: new Date().toISOString(),
@@ -106694,9 +107083,9 @@ async function resolveLinearActor(linearUserId, email, name, workspaceId, sample
106694
107083
  sampleContext: sampleContext ? sampleContext.slice(0, 100) : null
106695
107084
  },
106696
107085
  valueType: "json",
106697
- expiresAt: Date.now() + UNMAPPED_TTL_MS4
107086
+ expiresAt: Date.now() + UNMAPPED_TTL_MS5
106698
107087
  });
106699
- await incrKv2(UNMAPPED_NAMESPACE4, `${linearUserId}:count`, 1);
107088
+ await incrKv2(UNMAPPED_NAMESPACE5, `${linearUserId}:count`, 1);
106700
107089
  return;
106701
107090
  }
106702
107091
  var REQUEST_SECTION_LABEL = "Request (comment that opened this session)";
@@ -106808,7 +107197,7 @@ async function handleAgentSessionEvent(event) {
106808
107197
  }
106809
107198
  return;
106810
107199
  }
106811
- const lead = await findLeadAgent6();
107200
+ const lead = await findLeadAgent7();
106812
107201
  const sessionSection = sessionUrl ? `
106813
107202
  Session: ${sessionUrl}` : "";
106814
107203
  const requestSection = buildSessionRequestSection(event, actorName);
@@ -107012,7 +107401,7 @@ async function handleAgentSessionPrompted(event) {
107012
107401
  return;
107013
107402
  }
107014
107403
  }
107015
- const lead = await findLeadAgent6();
107404
+ const lead = await findLeadAgent7();
107016
107405
  const activity = event.agentActivity;
107017
107406
  const promptUser = activity?.user;
107018
107407
  const promptedActorLinearId = promptUser ? String(promptUser.id ?? "") : "";
@@ -107294,7 +107683,7 @@ function shouldSkipForLoopPrevention2(sync) {
107294
107683
  }
107295
107684
 
107296
107685
  // src/linear/app.ts
107297
- var initialized6 = false;
107686
+ var initialized7 = false;
107298
107687
  var unsubscribeRefresh = null;
107299
107688
  function isLinearEnabled() {
107300
107689
  if (isEnvFlagEnabled("LINEAR_DISABLE", false))
@@ -107309,12 +107698,12 @@ function resetLinear() {
107309
107698
  unsubscribeRefresh();
107310
107699
  unsubscribeRefresh = null;
107311
107700
  }
107312
- initialized6 = false;
107701
+ initialized7 = false;
107313
107702
  }
107314
107703
  async function initLinear() {
107315
- if (initialized6)
107704
+ if (initialized7)
107316
107705
  return isLinearEnabled();
107317
- initialized6 = true;
107706
+ initialized7 = true;
107318
107707
  if (!isLinearEnabled()) {
107319
107708
  console.log("[Linear] Integration disabled or LINEAR_CLIENT_ID not set");
107320
107709
  return false;
@@ -108019,7 +108408,7 @@ async function reloadGlobalConfigsAndIntegrations() {
108019
108408
  return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
108020
108409
  }
108021
108410
  async function reloadGlobalConfigsAndIntegrationsInner() {
108022
- const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-arytgj5q.js");
108411
+ const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-sepja052.js");
108023
108412
  const wasEmbeddingsConfigured = getEmbeddingProvider().isConfigured();
108024
108413
  const updated = await loadGlobalConfigsIntoEnv(true);
108025
108414
  await syncTelemetryEnabled("settings").catch((err) => {
@@ -108035,10 +108424,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
108035
108424
  integrations.push("embeddings");
108036
108425
  }
108037
108426
  if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
108038
- import("./boot-reembed-b9c3az3c.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
108427
+ import("./boot-reembed-n4wq5dd2.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
108039
108428
  console.error("[config-reload] memory backfill failed (non-fatal):", err);
108040
108429
  });
108041
- import("./boot-reembed-qdkvxeem.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
108430
+ import("./boot-reembed-4xwq5tg0.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
108042
108431
  console.error("[config-reload] script backfill failed (non-fatal):", err);
108043
108432
  });
108044
108433
  }
@@ -108060,6 +108449,11 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
108060
108449
  teardownAzureDevOpsOutbound();
108061
108450
  if (isAzureDevOpsEnabled())
108062
108451
  initAzureDevOpsOutbound();
108452
+ resetBitbucket();
108453
+ resetBitbucketBotCache();
108454
+ initBitbucket();
108455
+ if (isBitbucketEnabled())
108456
+ integrations.push("bitbucket");
108063
108457
  resetLinear();
108064
108458
  if (await initLinear())
108065
108459
  integrations.push("linear");
@@ -115538,14 +115932,14 @@ var prMatcher = (content) => {
115538
115932
  }
115539
115933
  return results;
115540
115934
  };
115541
- function escapeRegExp2(value) {
115935
+ function escapeRegExp3(value) {
115542
115936
  return value.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
115543
115937
  }
115544
115938
  function agentFsPathRegex() {
115545
115939
  const appHosts = getConfiguredAppUrls().flatMap((value) => {
115546
115940
  try {
115547
115941
  const url = new URL(value);
115548
- return [escapeRegExp2(`${url.host}${url.pathname.replace(/\/+$/, "")}`)];
115942
+ return [escapeRegExp3(`${url.host}${url.pathname.replace(/\/+$/, "")}`)];
115549
115943
  } catch {
115550
115944
  return [];
115551
115945
  }
@@ -130365,7 +130759,7 @@ var registerScriptConnectionsTool = (server) => {
130365
130759
  };
130366
130760
  // src/tools/script-delete.ts
130367
130761
  init_zod();
130368
- var SCRIPT_DELETE_DESCRIPTION = "Remove a swarm-shared script from the catalog. Versions table preserves history.";
130762
+ var SCRIPT_DELETE_DESCRIPTION = "Permanently remove a swarm-shared script and all its versions from the catalog. This cannot be undone.";
130369
130763
  var registerScriptDeleteTool = (server) => {
130370
130764
  createToolRegistrar(server)("script-delete", {
130371
130765
  title: "Script Delete",
@@ -134934,7 +135328,7 @@ async function emitBudgetRefusalSideEffects(ctx, inserted) {
134934
135328
  console.warn(`[budget-refusal-notify] Failed to create follow-up task for budget refusal (task=${ctx.task.id.slice(0, 8)}): ${err}`);
134935
135329
  }
134936
135330
  }
134937
- import("./event-bus-9vpk8gmq.js").then(({ workflowEventBus }) => {
135331
+ import("./event-bus-3z78ep5n.js").then(({ workflowEventBus }) => {
134938
135332
  workflowEventBus.emit("task.budget_refused", {
134939
135333
  taskId: ctx.task.id,
134940
135334
  agentId: ctx.agentId,
@@ -135985,7 +136379,7 @@ var registerCreateWorkflowTool = (server) => {
135985
136379
  ` + "- 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
136380
  ` + "- 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
136381
  ` + `- 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.
136382
+ ` + "- 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
136383
  ` + "- 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
136384
  ` + "- 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
136385
  ` + "- 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 +137426,4 @@ async function createServer(opts = {}) {
137032
137426
  return server;
137033
137427
  }
137034
137428
 
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 };
137429
+ 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 };