@desplega.ai/agent-swarm 2.4.4 → 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 (382) hide show
  1. package/README.md +4 -2
  2. package/dist/{acp-adapter-thq04adh.js → acp-adapter-11gp67nr.js} +8 -6
  3. package/dist/{actions-j6ywh6x5.js → actions-8p2kze8j.js} +24 -22
  4. package/dist/{amp-adapter-k8b5xmj8.js → amp-adapter-z4qvhacj.js} +2 -2
  5. package/dist/{anthropic-messages-g6pqmqk4.js → anthropic-messages-txs190dd.js} +17 -20
  6. package/dist/{app-rb7vc02s.js → app-0qp0a2gk.js} +3 -3
  7. package/dist/{assistant-ftta1zjf.js → assistant-jedd3ktm.js} +27 -25
  8. package/dist/{azure-openai-responses-9dbmj346.js → azure-openai-responses-9kfwhmn7.js} +18 -13
  9. package/dist/{boot-reembed-xns7h5h9.js → boot-reembed-4xwq5tg0.js} +1 -1
  10. package/dist/{boot-reembed-srp6v6af.js → boot-reembed-n4wq5dd2.js} +1 -1
  11. package/dist/{boot-scrub-sweep-3qqrh2mz.js → boot-scrub-sweep-69h90xcq.js} +4 -4
  12. package/dist/{boot-seeds-9ks8hce7.js → boot-seeds-3vn0m9sg.js} +4 -4
  13. package/dist/{claude-adapter-k5ksyres.js → claude-adapter-221mvad5.js} +8 -6
  14. package/dist/{claude-managed-adapter-h2y889ge.js → claude-managed-adapter-gt6pa35d.js} +2 -2
  15. package/dist/{claude-managed-setup-n5a5eqks.js → claude-managed-setup-c3hp36ph.js} +4 -4
  16. package/dist/{claude-sdk-session-2j3j4kwn.js → claude-sdk-session-8thjsk5e.js} +9729 -9628
  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-amyhm3gj.js → cli-0y6f0ckq.js} +1 -1
  20. package/dist/{cli-4dg55wsk.js → cli-0z3vjrpm.js} +1 -1
  21. package/dist/{cli-pccfmtb5.js → cli-179xcyky.js} +11 -11
  22. package/dist/{cli-3r8samv3.js → cli-1f0gp9vz.js} +3 -2
  23. package/dist/{cli-hj3debgw.js → cli-1pr672hz.js} +3 -3
  24. package/dist/{cli-0bqteszy.js → cli-2nf3b08t.js} +328 -25
  25. package/dist/{cli-t7cyef5g.js → cli-36j4jnk3.js} +4 -4
  26. package/dist/{cli-er83cjbn.js → cli-3qv8naq8.js} +527 -231
  27. package/dist/cli-3zwye9sn.js +1193 -0
  28. package/dist/{cli-60cgh1rv.js → cli-459fk97x.js} +7 -7
  29. package/dist/{cli-xj0re5tm.js → cli-4w24f7z3.js} +1 -1
  30. package/dist/{cli-v3yr2gbg.js → cli-5kzk3472.js} +2198 -968
  31. package/dist/{cli-h7gc0b4r.js → cli-5m84zd2k.js} +55 -18
  32. package/dist/{cli-w6nadkh4.js → cli-5rvg1ddk.js} +5 -5
  33. package/dist/{cli-dvkmp9bt.js → cli-6ctwrf1z.js} +20 -10
  34. package/dist/{cli-9qtjfd60.js → cli-6rg2jn2y.js} +3 -2
  35. package/dist/{cli-2v045xyf.js → cli-7bwtc6yx.js} +3 -3
  36. package/dist/{cli-3cgngyd8.js → cli-7g40g8hq.js} +35 -17
  37. package/dist/{cli-q6r7t299.js → cli-92mqenkc.js} +2379 -154
  38. package/dist/{cli-cynvc9fj.js → cli-9ce2xw98.js} +8 -8
  39. package/dist/{cli-gqvh8d8a.js → cli-bgdtv62r.js} +36 -22
  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-p20r8w42.js → cli-fcc5qe3f.js} +763 -268
  44. package/dist/{cli-1ephgwnq.js → cli-fes51ya2.js} +3 -3
  45. package/dist/{cli-1d70crsy.js → cli-ftmq4nvk.js} +2 -2
  46. package/dist/{cli-qkhc5aqy.js → cli-fy1jyyym.js} +13 -13
  47. package/dist/{cli-s95dknxh.js → cli-g1cw7xtt.js} +1 -1
  48. package/dist/{cli-qje9k2nh.js → cli-g9ypd5en.js} +12 -2
  49. package/dist/{cli-74c1wpm0.js → cli-gpv60278.js} +1 -1
  50. package/dist/{cli-pemywhfq.js → cli-ha9rmwgq.js} +2 -1
  51. package/dist/{cli-bnz0r3kc.js → cli-j1eghqfm.js} +5 -5
  52. package/dist/{cli-2zqpkvtt.js → cli-jpxsrxcb.js} +1 -1
  53. package/dist/{cli-ejs3m1sx.js → cli-kxpfx2xr.js} +1 -1
  54. package/dist/{cli-37yb7307.js → cli-mbfj11fq.js} +1 -1
  55. package/dist/{cli-pnp2j5zg.js → cli-mmhj8vd7.js} +2 -2
  56. package/dist/{cli-xf234ws8.js → cli-n4c8e3s5.js} +2 -0
  57. package/dist/{cli-a0kcty51.js → cli-n6kmqngw.js} +2 -2
  58. package/dist/{cli-te6b5wvg.js → cli-nnvjb17s.js} +3 -3
  59. package/dist/{cli-1dmcq2eh.js → cli-nzfnt2gs.js} +1 -1
  60. package/dist/{cli-625tb7aq.js → cli-p859hcc8.js} +2 -2
  61. package/dist/{cli-smvcw9z5.js → cli-pasyvjmm.js} +1 -1
  62. package/dist/cli-pkaqk57w.js +128 -0
  63. package/dist/{cli-8nyhf7za.js → cli-qqzmjxkf.js} +129 -105
  64. package/dist/{cli-zrwpctp4.js → cli-r25qpaxt.js} +161 -63
  65. package/dist/{cli-nc35pxb7.js → cli-rh5smt8t.js} +19 -4
  66. package/dist/{cli-qwkcwjdn.js → cli-rycdaj0a.js} +1 -1
  67. package/dist/{cli-esxerzg7.js → cli-s4sntwt4.js} +2 -2
  68. package/dist/{cli-b8k7epj1.js → cli-segs7hx9.js} +8 -8
  69. package/dist/{cli-36ckw0wx.js → cli-stxdrqs2.js} +2 -2
  70. package/dist/{cli-vdm20wej.js → cli-sy8f9705.js} +4 -4
  71. package/dist/{cli-1m17dc9d.js → cli-ta8bd7th.js} +2 -2
  72. package/dist/{cli-2y91wnbh.js → cli-we0ra057.js} +222 -10
  73. package/dist/{cli-55qmbp6z.js → cli-x21dqn18.js} +5 -5
  74. package/dist/{cli-dqb4n629.js → cli-x6vf4sad.js} +11 -11
  75. package/dist/{cli-d2mb5s8a.js → cli-x77gen2p.js} +680 -440
  76. package/dist/{cli-vq97g1jq.js → cli-xawhpgc9.js} +95 -195
  77. package/dist/{cli-82d3nkc3.js → cli-xd4eqtr2.js} +2 -2
  78. package/dist/{cli-9fhkkpj5.js → cli-xt768r5m.js} +2 -2
  79. package/dist/{cli-zrk6jxv8.js → cli-y4x8ww6s.js} +2 -2
  80. package/dist/{cli-xc27fwzg.js → cli-y9jvxfhk.js} +3 -3
  81. package/dist/{cli-44159k28.js → cli-z63a269p.js} +2 -2
  82. package/dist/{cli-sm8rses9.js → cli-zfdp01hn.js} +8 -5
  83. package/dist/cli.js +31 -29
  84. package/dist/{cloudflare-workers-ai-system-one-ch2wxfcp.js → cloudflare-workers-ai-system-one-43v9qkjk.js} +7 -2
  85. package/dist/{codex-adapter-968xwfy7.js → codex-adapter-tcg1q3jk.js} +6 -4
  86. package/dist/{codex-login-m819c41r.js → codex-login-rn7c5gxt.js} +1 -1
  87. package/dist/{codex-session-runner-ht4z99fa.js → codex-session-runner-xfx4wd9x.js} +7 -5
  88. package/dist/{commands-pcymaeg9.js → commands-ew83nj70.js} +2 -2
  89. package/dist/{controller-fpjyk46r.js → controller-gnq1k1mf.js} +4 -4
  90. package/dist/{controllers-connect-mwzx1fh6.js → controllers-connect-tw1dan9r.js} +26 -24
  91. package/dist/{cursor-adapter-cp4s2e2f.js → cursor-adapter-yq5xgfcg.js} +1 -1
  92. package/dist/{db-xsjg9jqq.js → db-7gbc53fd.js} +14 -2
  93. package/dist/{db-sgd12bt9.js → db-t86xrnes.js} +3 -3
  94. package/dist/{devin-adapter-zgqadvnm.js → devin-adapter-4ycy4vrf.js} +1 -1
  95. package/dist/{dispatcher-x0jfw2c9.js → dispatcher-64bdyhps.js} +23 -21
  96. package/dist/{docker-fkgtr75t.js → docker-nfy2gc8t.js} +2 -2
  97. package/dist/{dsh-adapter-jrq7ma7h.js → dsh-adapter-tvhc4k2d.js} +1 -1
  98. package/dist/{e2b-16d6ch39.js → e2b-9gkdhm3c.js} +2 -2
  99. package/dist/{e2b-zn0b4w5w.js → e2b-cjtf8k1z.js} +2 -2
  100. package/dist/{easter-egg-3d-5cgynaja.js → easter-egg-3d-e4qv8dxj.js} +1 -1
  101. package/dist/{event-bus-9vpk8gmq.js → event-bus-3z78ep5n.js} +1 -1
  102. package/dist/{execute-t4e6m3rw.js → execute-0xpz8950.js} +85 -23
  103. package/dist/{external-channel-8njj4h3b.js → external-channel-e9nw24zv.js} +2 -2
  104. package/dist/{google-generative-ai-bmq8gkf3.js → google-generative-ai-mk9vcpe1.js} +15 -15
  105. package/dist/{google-vertex-b1rvp52s.js → google-vertex-q580kz8k.js} +20 -20
  106. package/dist/{grok-adapter-kkr97v2f.js → grok-adapter-v82srhrx.js} +9 -7
  107. package/dist/handlers-c9ajzhbn.js +41 -0
  108. package/dist/{heartbeat-wd03zhn0.js → heartbeat-2vqs1319.js} +26 -24
  109. package/dist/{hook-xzj2ts2p.js → hook-01nk13wx.js} +7 -5
  110. package/dist/{hook-f0vghj42.js → hook-jzpheegg.js} +9 -7
  111. package/dist/{http-4hwxv62p.js → http-fc1k6ec8.js} +859 -252
  112. package/dist/index-07ef7nkm.js +42 -0
  113. package/dist/{index-g6tbb6ve.js → index-31ceyf42.js} +1 -1
  114. package/dist/index-7yts8n9s.js +43 -0
  115. package/dist/{index-c4ykd0f1.js → index-dr94zbnh.js} +13348 -11611
  116. package/dist/index-q3t40ryv.js +46 -0
  117. package/dist/{index-ww2vznkp.js → index-sepja052.js} +1 -1
  118. package/dist/{index-97q4xn03.js → index-zdycv3ja.js} +135 -79
  119. package/dist/{index-g216q6jr.js → index-zsyx51ap.js} +1 -4
  120. package/dist/{keepalive-hrh7xnr9.js → keepalive-5nh2rhmr.js} +4 -4
  121. package/dist/lead-aayq64jn.js +79 -0
  122. package/dist/{llama-cpp-classify-vv43gswy.js → llama-cpp-classify-ee7vmd7q.js} +4 -1
  123. package/dist/{maintenance-e8wnwnqx.js → maintenance-hjhzdt3k.js} +1 -1
  124. package/dist/{mistral-conversations-1medfwv7.js → mistral-conversations-sd0xf1tn.js} +13 -13
  125. package/dist/{node-3v3f08f7.js → node-jzjj7r9x.js} +10 -9
  126. package/dist/{oauth-refresh-sweep-zm0yj4sj.js → oauth-refresh-sweep-y3n1knmd.js} +3 -3
  127. package/dist/{onboard-dtwcq603.js → onboard-1zq3m7db.js} +2 -2
  128. package/dist/{openai-codex-responses-de9pvs4d.js → openai-codex-responses-79s8xnbh.js} +29 -23
  129. package/dist/{openai-completions-mtqge3nf.js → openai-completions-tdbyts0x.js} +21 -20
  130. package/dist/{openai-decisions-ygk4kkxd.js → openai-decisions-bqhnjyfz.js} +2 -1
  131. package/dist/{openai-responses-dkyng71g.js → openai-responses-dm3t5vqp.js} +26 -17
  132. package/dist/{opencode-adapter-x4tqzhkh.js → opencode-adapter-e56086m1.js} +7 -5
  133. package/dist/{openrouter-images-wvv7camj.js → openrouter-images-ssttr1y4.js} +6 -3
  134. package/dist/{otel-impl-w3fbhpn0.js → otel-impl-h9yyza47.js} +2 -2
  135. package/dist/{pi-messages-nhh1pkz2.js → pi-messages-3nf8bq1a.js} +6 -4
  136. package/dist/{pi-mono-adapter-mcfkn9vf.js → pi-mono-adapter-tzps8f38.js} +9 -37
  137. package/dist/{pricing-refresh-j38dehfs.js → pricing-refresh-nevhat8h.js} +3 -3
  138. package/dist/{rbac-roles-ae8yttq4.js → rbac-roles-4y6ngvzq.js} +1 -1
  139. package/dist/{rbac-roles-ejxx9b35.js → rbac-roles-exbg8xb6.js} +2 -2
  140. package/dist/{registry-rxw10xzg.js → registry-ajhexe44.js} +1 -1
  141. package/dist/{render-v2-n16n0phe.js → render-v2-cfsh13z3.js} +3 -3
  142. package/dist/{resume-z0fgjc38.js → resume-5s2t0dbs.js} +10 -8
  143. package/dist/{runtime-xe3aqy4x.js → runtime-bt5pkpm1.js} +1 -1
  144. package/dist/{session-access-cv3mq6mc.js → session-access-dnbyp3cn.js} +6 -4
  145. package/dist/{setup-mafhj3yt.js → setup-1wj1y77j.js} +1 -1
  146. package/dist/{typesafe-system-one-2hgpayzy.js → typesafe-system-one-bre38hvs.js} +4 -2
  147. package/dist/{virtual-modules-4r3zkc20.js → virtual-modules-mnfbh5mr.js} +8 -2
  148. package/dist/{work-objects-8b86mgjp.js → work-objects-7mg6216g.js} +26 -24
  149. package/dist/worker-nwb789mg.js +79 -0
  150. package/dist/{x-y45mthwn.js → x-pbpezr0s.js} +2 -2
  151. package/openapi.json +793 -6
  152. package/package.json +11 -11
  153. package/src/apps/catalog.generated.json +206 -4
  154. package/src/apps/page-validator.ts +13 -1
  155. package/src/assets/key.ts +17 -0
  156. package/src/azure-devops/handlers.ts +1 -1
  157. package/src/be/chunking.ts +42 -9
  158. package/src/be/db/approvals.ts +18 -0
  159. package/src/be/db/session-moves.ts +164 -0
  160. package/src/be/db/session-tree.ts +384 -0
  161. package/src/be/db/tasks/draft-text.ts +15 -0
  162. package/src/be/db/tasks/read.ts +54 -5
  163. package/src/be/db/workflow-runs.ts +96 -0
  164. package/src/be/db.ts +85 -237
  165. package/src/be/memory/index-content.ts +36 -17
  166. package/src/be/memory/providers/openai-embedding.ts +115 -61
  167. package/src/be/memory/providers/sqlite-store.ts +69 -23
  168. package/src/be/memory/reranker.ts +31 -1
  169. package/src/be/memory/search-candidates.ts +47 -0
  170. package/src/be/memory/types.ts +14 -0
  171. package/src/be/onboarding.ts +3 -0
  172. package/src/be/scripts/typecheck.ts +2 -0
  173. package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +106 -54
  174. package/src/be/seed-scripts/index.ts +2 -2
  175. package/src/be/skill-sync.ts +43 -2
  176. package/src/be/swarm-config-guard.ts +25 -1
  177. package/src/be/task-attachment-store.ts +30 -0
  178. package/src/bitbucket/api.ts +81 -0
  179. package/src/bitbucket/auth.ts +64 -0
  180. package/src/bitbucket/handlers.ts +434 -0
  181. package/src/bitbucket/index.ts +28 -0
  182. package/src/bitbucket/templates.ts +134 -0
  183. package/src/bitbucket/types.ts +65 -0
  184. package/src/commands/runner.ts +55 -3
  185. package/src/e2b/env.ts +1 -0
  186. package/src/extensions/catalog.generated.json +4 -4
  187. package/src/extensions/contract-types.generated.ts +1 -1
  188. package/src/extensions/contract.ts +9 -2
  189. package/src/extensions/post-bridge.ts +1 -0
  190. package/src/fs/provider.ts +13 -1
  191. package/src/github/handlers.ts +6 -6
  192. package/src/gitlab/handlers.ts +5 -5
  193. package/src/heartbeat/heartbeat.ts +31 -11
  194. package/src/http/assets.ts +14 -2
  195. package/src/http/core.ts +12 -0
  196. package/src/http/fs.ts +54 -34
  197. package/src/http/index.ts +4 -0
  198. package/src/http/mcp-body.ts +37 -0
  199. package/src/http/mcp-user.ts +3 -5
  200. package/src/http/mcp.ts +6 -7
  201. package/src/http/memory.ts +26 -15
  202. package/src/http/onboarding.ts +1 -0
  203. package/src/http/page-proxy.ts +61 -5
  204. package/src/http/pages-public.ts +27 -44
  205. package/src/http/pages.ts +4 -4
  206. package/src/http/script-runs.ts +2 -0
  207. package/src/http/sessions.ts +366 -12
  208. package/src/http/skills.ts +48 -1
  209. package/src/http/tasks.ts +1 -1
  210. package/src/http/users.ts +13 -1
  211. package/src/http/webhooks.ts +141 -0
  212. package/src/integrations/chat-sdk/adapters.ts +24 -4
  213. package/src/integrations/chat-sdk/attachments.ts +90 -12
  214. package/src/integrations/chat-sdk/facts.ts +138 -0
  215. package/src/integrations/chat-sdk/inbound.ts +156 -8
  216. package/src/integrations/chat-sdk/limits.ts +24 -0
  217. package/src/integrations/chat-sdk/outbound-files.ts +186 -0
  218. package/src/integrations/chat-sdk/outbound.ts +272 -5
  219. package/src/integrations/chat-sdk/relay.ts +4 -1
  220. package/src/integrations/chat-sdk/router.ts +28 -2
  221. package/src/integrations/chat-sdk/steering.ts +9 -0
  222. package/src/integrations/chat-sdk/templates.ts +14 -0
  223. package/src/integrations/chat-sdk/thread-buffer.ts +4 -0
  224. package/src/mcp-limits.ts +20 -0
  225. package/src/pages/browser-sdk.ts +8 -3
  226. package/src/pages/feedback-overlay.ts +1 -1
  227. package/src/providers/acp-targets.ts +1 -1
  228. package/src/providers/amp-adapter.ts +1 -1
  229. package/src/providers/codex-adapter.ts +106 -119
  230. package/src/providers/codex-agents-md.ts +35 -229
  231. package/src/providers/cursor-adapter.ts +1 -1
  232. package/src/providers/pi-mono-adapter.ts +5 -53
  233. package/src/realtime/transport.ts +1 -2
  234. package/src/script-workflows/workflow-ctx.ts +1 -0
  235. package/src/scripts-runtime/types/stdlib.d.ts +2 -0
  236. package/src/scripts-runtime/types/swarm-extension.d.ts +14 -4
  237. package/src/scripts-runtime/types/swarm-sdk.d.ts +2 -0
  238. package/src/server-user.ts +2 -0
  239. package/src/server.ts +2 -0
  240. package/src/slack/assistant.ts +2 -2
  241. package/src/slack/files.ts +2 -0
  242. package/src/slack/handlers.test.ts +158 -0
  243. package/src/slack/handlers.ts +23 -32
  244. package/src/slack/inbound-files.ts +39 -6
  245. package/src/slack/thread-buffer.ts +2 -1
  246. package/src/tasks/context-key.ts +61 -1
  247. package/src/tasks/task-terminal-effects.ts +21 -17
  248. package/src/tests/apps-card-grid.test.ts +197 -0
  249. package/src/tests/apps-catalog-additions.test.ts +120 -0
  250. package/src/tests/apps-tree.test.ts +129 -0
  251. package/src/tests/bitbucket-auth.test.ts +156 -0
  252. package/src/tests/bitbucket-handlers.test.ts +425 -0
  253. package/src/tests/bitbucket-webhook.test.ts +220 -0
  254. package/src/tests/chat-sdk-attachments-reply.test.ts +52 -0
  255. package/src/tests/chat-sdk-config.test.ts +11 -0
  256. package/src/tests/chat-sdk-facts.test.ts +23 -0
  257. package/src/tests/chat-sdk-inbound.test.ts +597 -4
  258. package/src/tests/chat-sdk-outbound-files.test.ts +652 -0
  259. package/src/tests/chat-sdk-telegram-markdown.test.ts +92 -0
  260. package/src/tests/codex-adapter.test.ts +167 -242
  261. package/src/tests/config-api-only-keys.test.ts +9 -0
  262. package/src/tests/context-key.test.ts +50 -0
  263. package/src/tests/core-auth.test.ts +5 -0
  264. package/src/tests/cors-allowlist.test.ts +1 -1
  265. package/src/tests/db-task-read-contract.test.ts +7 -0
  266. package/src/tests/db-task-write-contract.test.ts +6 -0
  267. package/src/tests/docs-index-footprint.test.js +3 -3
  268. package/src/tests/extensions-example-slack-reply-gate.test.ts +262 -91
  269. package/src/tests/fixtures/bitbucket/pullrequest-comment-created-inline.json +174 -0
  270. package/src/tests/fixtures/bitbucket/pullrequest-comment-created.json +170 -0
  271. package/src/tests/fixtures/bitbucket/pullrequest-created-mention.json +132 -0
  272. package/src/tests/fixtures/bitbucket/pullrequest-created-reviewer.json +140 -0
  273. package/src/tests/fixtures/bitbucket/pullrequest-fulfilled.json +134 -0
  274. package/src/tests/fixtures/bitbucket/pullrequest-rejected.json +133 -0
  275. package/src/tests/generate-mcp-docs.test.ts +101 -0
  276. package/src/tests/gitlab-handlers.test.ts +3 -3
  277. package/src/tests/gitlab-vcs-db.test.ts +4 -4
  278. package/src/tests/heartbeat-checklist.test.ts +33 -0
  279. package/src/tests/heartbeat-jev-gate-credentials.test.ts +44 -0
  280. package/src/tests/heartbeat-jev-gate.test.ts +242 -1
  281. package/src/tests/integration-disable-flags.test.ts +36 -0
  282. package/src/tests/kv-page-proxy.test.ts +91 -5
  283. package/src/tests/launch-password-rejection.test.ts +2 -2
  284. package/src/tests/mcp-input-caps.test.ts +294 -0
  285. package/src/tests/mcp-tools.test.ts +1 -1
  286. package/src/tests/memory-chunked-search-starvation.test.ts +200 -0
  287. package/src/tests/memory-embedding-input-cap.test.ts +114 -0
  288. package/src/tests/memory.test.ts +14 -0
  289. package/src/tests/onboarding.test.ts +12 -0
  290. package/src/tests/page-guest-session.test.ts +19 -8
  291. package/src/tests/page-proxy-authed.test.ts +1 -1
  292. package/src/tests/page-proxy.test.ts +17 -10
  293. package/src/tests/page-session.test.ts +102 -1
  294. package/src/tests/pages-authed-mode.test.ts +82 -12
  295. package/src/tests/pages-password-mode.test.ts +5 -5
  296. package/src/tests/pi-codemode.test.ts +8 -2
  297. package/src/tests/preload-env.test.ts +57 -0
  298. package/src/tests/preload.ts +21 -0
  299. package/src/tests/prompt-template-remaining.test.ts +38 -0
  300. package/src/tests/realtime-transport.test.ts +13 -7
  301. package/src/tests/run-root-coverage.test.ts +39 -0
  302. package/src/tests/runner-bitbucket-vcs.test.ts +191 -0
  303. package/src/tests/runner-skills-refresh.test.ts +58 -0
  304. package/src/tests/script-runs-http.test.ts +84 -0
  305. package/src/tests/scripts-http.test.ts +10 -1
  306. package/src/tests/secret-scrubber.test.ts +15 -0
  307. package/src/tests/sessions-move.test.ts +576 -0
  308. package/src/tests/sessions-tree.test.ts +493 -0
  309. package/src/tests/skill-files-http.test.ts +50 -0
  310. package/src/tests/skills-bundle.test.ts +99 -0
  311. package/src/tests/swarm-config-export-to-env.test.ts +23 -3
  312. package/src/tests/task-audio-transcription.test.ts +299 -0
  313. package/src/tests/task-completion-memory-chunking.test.ts +434 -0
  314. package/src/tests/task-terminal-secret-scrub.test.ts +6 -1
  315. package/src/tests/transcription.test.ts +299 -0
  316. package/src/tests/vcs-bitbucket.test.ts +91 -0
  317. package/src/tests/vcs-provider-isolation.test.ts +123 -0
  318. package/src/tests/vcs-provider.test.ts +16 -1
  319. package/src/tests/vcs-tracking.test.ts +3 -3
  320. package/src/tests/workflow-foreach-bodies.test.ts +637 -0
  321. package/src/tests/workflow-foreach-concurrency.test.ts +342 -0
  322. package/src/tests/workflow-foreach-retry.test.ts +537 -0
  323. package/src/tests/workflow-foreach.test.ts +44 -23
  324. package/src/tests/workflow-step-claims.test.ts +6 -6
  325. package/src/tests/workflow-system-one-decision-providers.test.ts +98 -1
  326. package/src/tests/workflow-system-one-decision.test.ts +2 -1
  327. package/src/tests/workflow-tla-races.test.ts +2 -2
  328. package/src/tools/chat-access.ts +10 -0
  329. package/src/tools/chat-post.ts +31 -11
  330. package/src/tools/chat-reply.ts +32 -10
  331. package/src/tools/memory-search.ts +3 -1
  332. package/src/tools/script-delete.ts +1 -1
  333. package/src/tools/system-one-decide.ts +17 -4
  334. package/src/tools/workflows/create-workflow.ts +5 -3
  335. package/src/types.ts +9 -2
  336. package/src/utils/config-env-export.ts +4 -1
  337. package/src/utils/page-session.ts +133 -20
  338. package/src/utils/secret-scrubber.ts +4 -0
  339. package/src/utils/skills-refresh.ts +83 -43
  340. package/src/utils/transcription.ts +246 -0
  341. package/src/vcs/bitbucket.ts +58 -0
  342. package/src/vcs/index.ts +2 -0
  343. package/src/vcs/types.ts +2 -2
  344. package/src/workflows/approval-resolution.ts +4 -1
  345. package/src/workflows/checkpoint.ts +9 -1
  346. package/src/workflows/constants.ts +3 -0
  347. package/src/workflows/definition.ts +48 -17
  348. package/src/workflows/engine.ts +25 -15
  349. package/src/workflows/executors/foreach.ts +45 -99
  350. package/src/workflows/executors/system-one-decision.ts +28 -7
  351. package/src/workflows/executors/system-one-providers.ts +39 -4
  352. package/src/workflows/foreach-body.ts +146 -0
  353. package/src/workflows/foreach-driver.ts +552 -0
  354. package/src/workflows/foreach-join.ts +206 -7
  355. package/src/workflows/node-timeout.ts +21 -0
  356. package/src/workflows/recovery.ts +68 -3
  357. package/src/workflows/resume.ts +221 -43
  358. package/src/workflows/retry-poller.ts +39 -24
  359. package/src/workflows/step-input.ts +59 -0
  360. package/src/workflows/task-step-routing.ts +114 -56
  361. package/templates/extensions/slack-reply-gate/README.md +24 -22
  362. package/templates/extensions/slack-reply-gate/hooks.ts +146 -95
  363. package/templates/extensions/slack-reply-gate/manifest.json +2 -2
  364. package/templates/skills/apps/SKILL.md +28 -6
  365. package/templates/skills/apps/content.md +28 -6
  366. package/templates/skills/chat-sdk/content.md +6 -2
  367. package/templates/skills/code-quality/content.md +2 -1
  368. package/templates/skills/heartbeat-runbook/content.md +5 -5
  369. package/templates/skills/pages/content.md +6 -4
  370. package/templates/skills/slack-interaction/content.md +5 -0
  371. package/templates/skills/swarm-scripts/SKILL.md +2 -2
  372. package/templates/skills/swarm-scripts/content.md +2 -2
  373. package/templates/skills/work-on-task/SKILL.md +1 -1
  374. package/templates/skills/work-on-task/content.md +1 -1
  375. package/dist/cli-51y09c6p.js +0 -2657
  376. package/dist/cli-yw91rnmw.js +0 -13
  377. package/dist/handlers-0pvee9nw.js +0 -39
  378. package/dist/index-gdh8jrdm.js +0 -43
  379. package/dist/index-hg0x2cdv.js +0 -40
  380. package/dist/index-thm0y6a8.js +0 -41
  381. package/dist/lead-ee8vazz2.js +0 -77
  382. package/dist/worker-16s75hm5.js +0 -77
@@ -0,0 +1,342 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
+ import { unlink } from "node:fs/promises";
3
+ import * as db from "../be/db";
4
+ import {
5
+ cancelTask,
6
+ closeDb,
7
+ completeTask,
8
+ createAgent,
9
+ createWorkflow,
10
+ detachTaskFromWorkflowRunStep,
11
+ failTask,
12
+ getDbClient,
13
+ getTaskByWorkflowRunStepId,
14
+ getWorkflowRun,
15
+ getWorkflowRunStepsByRunId,
16
+ initDb,
17
+ } from "../be/db";
18
+ import type { Workflow, WorkflowDefinition, WorkflowRun, WorkflowRunStep } from "../types";
19
+ import { validateDefinition } from "../workflows/definition";
20
+ import { startWorkflowExecution } from "../workflows/engine";
21
+ import { workflowEventBus } from "../workflows/event-bus";
22
+ import type { ExecutorDependencies } from "../workflows/executors/base";
23
+ import { createExecutorRegistry } from "../workflows/executors/registry";
24
+ import {
25
+ _resetForeachOwnershipForTests,
26
+ drainForeachDrives,
27
+ driveForeach,
28
+ } from "../workflows/foreach-driver";
29
+ import { buildForeachAggregate } from "../workflows/foreach-join";
30
+ import { recoverIncompleteRuns } from "../workflows/recovery";
31
+ import { setupWorkflowResumeListener } from "../workflows/resume";
32
+
33
+ const TEST_DB_PATH = "./test-workflow-foreach-concurrency.sqlite";
34
+
35
+ const deps: ExecutorDependencies = {
36
+ db,
37
+ eventBus: workflowEventBus,
38
+ interpolate: (t: string) => t,
39
+ };
40
+ const registry = createExecutorRegistry(deps);
41
+
42
+ let teardown: (() => void) | undefined;
43
+ let agentId: string;
44
+
45
+ beforeAll(async () => {
46
+ await removeDbFiles();
47
+ initDb(TEST_DB_PATH);
48
+ agentId = (await createAgent({ name: "Capped", status: "idle" })).id;
49
+ teardown = setupWorkflowResumeListener(workflowEventBus, registry);
50
+ });
51
+
52
+ afterAll(async () => {
53
+ teardown?.();
54
+ await drainForeachDrives();
55
+ closeDb();
56
+ await removeDbFiles();
57
+ });
58
+
59
+ describe("foreach config validation", () => {
60
+ test("failurePolicy accepts the two policies and rejects anything else", () => {
61
+ for (const policy of ["fail-fast", "collect-outcomes"]) {
62
+ expect(validateDefinition(fanOut({ failurePolicy: policy })).valid).toBe(true);
63
+ }
64
+ const invalid = validateDefinition(fanOut({ failurePolicy: "best-effort" }));
65
+ expect(invalid.valid).toBe(false);
66
+ expect(
67
+ invalid.errors.some((error) => error.includes('Node "fan" foreach config.failurePolicy')),
68
+ ).toBe(true);
69
+ });
70
+ });
71
+
72
+ describe("foreach concurrency cap", () => {
73
+ test("concurrency 2 over 5 items keeps at most 2 in flight; each completion starts one more", async () => {
74
+ const runId = await startRun(5, { concurrency: 2 });
75
+ expect(await inFlightTasks(runId)).toHaveLength(2);
76
+ expect((await children(runId)).filter((step) => step.status === "pending")).toHaveLength(3);
77
+
78
+ for (let done = 1; done <= 5; done++) {
79
+ const [next] = await inFlightTasks(runId);
80
+ await completeTask(next!.taskId, `out ${next!.nodeId}`);
81
+ await waitForStep(next!.stepId, "completed");
82
+ await drainForeachDrives();
83
+ const remaining = 5 - done;
84
+ expect(await inFlightTasks(runId)).toHaveLength(Math.min(2, remaining));
85
+ expect(await boundTaskCount(runId)).toBe(Math.min(5, done + 2));
86
+ }
87
+
88
+ const run = await waitForRun(runId, (r) => r.status === "completed");
89
+ const aggregate = (run.context as Record<string, unknown>).fan as {
90
+ okCount: number;
91
+ failedCount: number;
92
+ };
93
+ expect(aggregate).toMatchObject({ okCount: 5, failedCount: 0 });
94
+ });
95
+
96
+ test("the cap holds after a restart: two recovery sweeps start no new item", async () => {
97
+ const runId = await startRun(5, { concurrency: 2 });
98
+ const inFlight = await inFlightTasks(runId);
99
+ expect(inFlight).toHaveLength(2);
100
+
101
+ // A restart drops in-process ownership; one in-flight item is left
102
+ // `running` with no owner (crash between claim and park).
103
+ _resetForeachOwnershipForTests();
104
+ await setStatus(inFlight[0]!.stepId, "running");
105
+
106
+ await recoverIncompleteRuns(registry);
107
+ await recoverIncompleteRuns(registry);
108
+ await drainForeachDrives();
109
+
110
+ expect(await boundTaskCount(runId)).toBe(2);
111
+ const steps = await children(runId);
112
+ expect(steps.filter((step) => step.status === "waiting")).toHaveLength(2);
113
+ expect(steps.filter((step) => step.status === "pending")).toHaveLength(3);
114
+ // The orphan reconnected to its own task instead of starting a second one.
115
+ expect((await getTaskByWorkflowRunStepId(inFlight[0]!.stepId))?.id).toBe(inFlight[0]!.taskId);
116
+ });
117
+
118
+ test("concurrent drives never exceed the cap", async () => {
119
+ const runId = await startRun(5, { concurrency: 2 });
120
+ // Back to the state right after materialization: every item queued.
121
+ for (const { taskId, stepId } of await inFlightTasks(runId)) {
122
+ await detachTaskFromWorkflowRunStep(taskId);
123
+ await setStatus(stepId, "pending");
124
+ }
125
+ _resetForeachOwnershipForTests();
126
+
127
+ await Promise.all([
128
+ driveForeach(runId, "fan", registry),
129
+ driveForeach(runId, "fan", registry),
130
+ driveForeach(runId, "fan", registry),
131
+ ]);
132
+
133
+ const steps = await children(runId);
134
+ expect(
135
+ steps.filter((step) => step.status === "running" || step.status === "waiting"),
136
+ ).toHaveLength(2);
137
+ expect(await boundTaskCount(runId)).toBe(2);
138
+ });
139
+ });
140
+
141
+ describe("foreach failure policies", () => {
142
+ test("fail-fast cancels queued items, never starts them, and fails the run", async () => {
143
+ const runId = await startRun(4, { concurrency: 1, failurePolicy: "fail-fast" });
144
+ const [first] = await inFlightTasks(runId);
145
+ await completeTask(first!.taskId, "first ok");
146
+ await waitForStep(first!.stepId, "completed");
147
+ await drainForeachDrives();
148
+
149
+ const [second] = await inFlightTasks(runId);
150
+ expect(second!.nodeId).toBe("fan#i1");
151
+ await failTask(second!.taskId, "item two broke");
152
+ const run = await waitForRun(runId, (r) => r.status === "failed");
153
+ expect(run.error).toContain("item two broke");
154
+
155
+ const steps = await children(runId);
156
+ const byNode = Object.fromEntries(steps.map((step) => [step.nodeId, step]));
157
+ expect(byNode["fan#i0"]?.status).toBe("completed");
158
+ expect(byNode["fan#i1"]?.status).toBe("failed");
159
+ for (const nodeId of ["fan#i2", "fan#i3"]) {
160
+ expect(byNode[nodeId]?.status).toBe("cancelled");
161
+ expect(byNode[nodeId]?.error).toBe("not started: fail-fast after item i1 failed");
162
+ expect(await getTaskByWorkflowRunStepId(byNode[nodeId]!.id)).toBeNull();
163
+ }
164
+ // The parent stays open, so a run retry can resume it.
165
+ expect((await stepByNodeId(runId, "fan"))?.status).toBe("waiting");
166
+ });
167
+
168
+ test("fail-fast lets an in-flight sibling finish without reviving the run", async () => {
169
+ const runId = await startRun(3, { concurrency: 2, failurePolicy: "fail-fast" });
170
+ const [first, second] = await inFlightTasks(runId);
171
+ await failTask(first!.taskId, "first broke");
172
+ await waitForRun(runId, (r) => r.status === "failed");
173
+ expect((await stepByNodeId(runId, "fan#i2"))?.status).toBe("cancelled");
174
+
175
+ await completeTask(second!.taskId, "second finished late");
176
+ await waitForStep(second!.stepId, "completed");
177
+ await drainForeachDrives();
178
+ expect((await getWorkflowRun(runId))?.status).toBe("failed");
179
+ expect(await stepByNodeId(runId, "after")).toBeUndefined();
180
+ });
181
+
182
+ test("collect-outcomes runs every item and routes the join with the failures counted", async () => {
183
+ // onNodeFailure stays the default "fail": the node's policy wins.
184
+ const runId = await startRun(4, { concurrency: 2, failurePolicy: "collect-outcomes" });
185
+ let failed = false;
186
+ for (;;) {
187
+ const [next] = await inFlightTasks(runId);
188
+ if (!next) break;
189
+ if (!failed) {
190
+ await failTask(next.taskId, "one item broke");
191
+ failed = true;
192
+ } else {
193
+ await completeTask(next.taskId, `out ${next.nodeId}`);
194
+ }
195
+ await waitForStep(next.stepId, "completed");
196
+ await drainForeachDrives();
197
+ }
198
+ const run = await waitForRun(runId, (r) => r.status === "completed");
199
+ const aggregate = (run.context as Record<string, unknown>).fan as {
200
+ okCount: number;
201
+ failedCount: number;
202
+ results: Array<{ itemKey: string; status: string }>;
203
+ };
204
+ expect(aggregate.okCount).toBe(3);
205
+ expect(aggregate.failedCount).toBe(1);
206
+ expect(aggregate.results.find((result) => result.itemKey === "i0")?.status).toBe("failed");
207
+ expect((await stepByNodeId(runId, "after"))?.status).toBe("completed");
208
+ expect(run.error ?? "").not.toContain("Partial failure");
209
+ });
210
+
211
+ test("a cancelled item counts as failed under collect-outcomes", async () => {
212
+ const runId = await startRun(2, { failurePolicy: "collect-outcomes" });
213
+ const [first, second] = await inFlightTasks(runId);
214
+ await cancelTask(first!.taskId, "operator cancelled");
215
+ await waitForStep(first!.stepId, "completed");
216
+ await completeTask(second!.taskId, "ok");
217
+ const run = await waitForRun(runId, (r) => r.status === "completed");
218
+ expect((run.context as Record<string, unknown>).fan).toMatchObject({
219
+ okCount: 1,
220
+ failedCount: 1,
221
+ });
222
+ });
223
+
224
+ test("a cancelled item counts as failed and cancelled in the aggregate under fail-fast", () => {
225
+ const row = (nodeId: string, status: string, index: number) =>
226
+ ({ nodeId, status, input: { itemKey: nodeId.slice(4), index }, output: null }) as never;
227
+ const aggregate = buildForeachAggregate([
228
+ row("fan#a", "completed", 0),
229
+ row("fan#b", "failed", 1),
230
+ row("fan#c", "cancelled", 2),
231
+ ]);
232
+ expect(aggregate).toMatchObject({ okCount: 1, failedCount: 2, cancelledCount: 1 });
233
+ });
234
+
235
+ test("without concurrency or failurePolicy the aggregate keeps its exact shape", async () => {
236
+ const runId = await startRun(2, {});
237
+ for (const { taskId } of await inFlightTasks(runId)) await completeTask(taskId, "ok");
238
+ const run = await waitForRun(runId, (r) => r.status === "completed");
239
+ const aggregate = (run.context as Record<string, unknown>).fan as Record<string, unknown>;
240
+ expect(Object.keys(aggregate).sort()).toEqual(["failedCount", "okCount", "results"]);
241
+ });
242
+ });
243
+
244
+ /** `fan`, an agent-task foreach over the trigger items, then `after`. */
245
+ function fanOut(extra: Record<string, unknown>): WorkflowDefinition {
246
+ return {
247
+ nodes: [
248
+ {
249
+ id: "fan",
250
+ type: "foreach",
251
+ config: {
252
+ over: "{{trigger.items}}",
253
+ itemKey: "id",
254
+ ...extra,
255
+ body: { type: "agent-task", config: { agentId, template: "Item {{item.id}}" } },
256
+ },
257
+ next: "after",
258
+ },
259
+ { id: "after", type: "notify", config: { channel: "swarm", template: "done" } },
260
+ ],
261
+ };
262
+ }
263
+
264
+ async function startRun(count: number, extra: Record<string, unknown>): Promise<string> {
265
+ const workflow = await makeWorkflow(fanOut(extra));
266
+ const items = Array.from({ length: count }, (_, index) => ({ id: `i${index}` }));
267
+ const runId = await startWorkflowExecution(workflow, { items }, registry);
268
+ await drainForeachDrives();
269
+ return runId;
270
+ }
271
+
272
+ function makeWorkflow(definition: WorkflowDefinition): Promise<Workflow> {
273
+ return createWorkflow({ name: `foreach-cap-${crypto.randomUUID()}`, definition });
274
+ }
275
+
276
+ async function children(runId: string): Promise<WorkflowRunStep[]> {
277
+ return (await getWorkflowRunStepsByRunId(runId)).filter((step) => step.nodeId.startsWith("fan#"));
278
+ }
279
+
280
+ async function stepByNodeId(runId: string, nodeId: string) {
281
+ return (await getWorkflowRunStepsByRunId(runId)).find((step) => step.nodeId === nodeId);
282
+ }
283
+
284
+ /** In-flight items with their bound task, in item order. */
285
+ async function inFlightTasks(
286
+ runId: string,
287
+ ): Promise<Array<{ stepId: string; nodeId: string; taskId: string }>> {
288
+ const result = [];
289
+ for (const step of await children(runId)) {
290
+ if (step.status !== "waiting" && step.status !== "running") continue;
291
+ const task = await getTaskByWorkflowRunStepId(step.id);
292
+ if (task) result.push({ stepId: step.id, nodeId: step.nodeId, taskId: task.id });
293
+ }
294
+ return result;
295
+ }
296
+
297
+ async function boundTaskCount(runId: string): Promise<number> {
298
+ const row = await getDbClient().get<{ count: number }>(
299
+ `SELECT COUNT(*) AS count FROM agent_tasks t
300
+ JOIN workflow_run_steps s ON s.id = t.workflowRunStepId
301
+ WHERE s.runId = ? AND s.nodeId LIKE 'fan#%'`,
302
+ [runId],
303
+ );
304
+ return row?.count ?? 0;
305
+ }
306
+
307
+ async function setStatus(stepId: string, status: string): Promise<void> {
308
+ await getDbClient().run("UPDATE workflow_run_steps SET status = ? WHERE id = ?", [
309
+ status,
310
+ stepId,
311
+ ]);
312
+ }
313
+
314
+ async function waitForStep(stepId: string, status: string): Promise<void> {
315
+ const deadline = Date.now() + 3_000;
316
+ while (Date.now() < deadline) {
317
+ if ((await db.getWorkflowRunStep(stepId))?.status === status) return;
318
+ await Bun.sleep(10);
319
+ }
320
+ throw new Error(`Timed out waiting for step ${stepId} to be ${status}`);
321
+ }
322
+
323
+ async function waitForRun(
324
+ runId: string,
325
+ done: (run: WorkflowRun) => boolean,
326
+ timeoutMs = 3_000,
327
+ ): Promise<WorkflowRun> {
328
+ const deadline = Date.now() + timeoutMs;
329
+ let run: WorkflowRun | null = null;
330
+ while (Date.now() < deadline) {
331
+ run = await getWorkflowRun(runId);
332
+ if (run && done(run)) return run;
333
+ await Bun.sleep(10);
334
+ }
335
+ throw new Error(`Timed out waiting for run ${runId}; last status ${run?.status} ${run?.error}`);
336
+ }
337
+
338
+ async function removeDbFiles(): Promise<void> {
339
+ for (const suffix of ["", "-wal", "-shm"]) {
340
+ await unlink(TEST_DB_PATH + suffix).catch(() => {});
341
+ }
342
+ }