@desplega.ai/agent-swarm 2.6.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/README.md +2 -0
  2. package/dist/{acp-adapter-dgfakfpw.js → acp-adapter-8dn5tq56.js} +6 -6
  3. package/dist/{actions-fbqma8aa.js → actions-3r6gw7dy.js} +18 -18
  4. package/dist/{amp-adapter-en0jy6hs.js → amp-adapter-wjtq413p.js} +3 -3
  5. package/dist/{anthropic-messages-txs190dd.js → anthropic-messages-n4cby1rz.js} +4 -4
  6. package/dist/{app-k8a5cgpp.js → app-d53yhykk.js} +3 -3
  7. package/dist/{assistant-a16433gr.js → assistant-ksrawj3k.js} +20 -20
  8. package/dist/{boot-reembed-6c1sjfnr.js → boot-reembed-fxfw17m2.js} +11 -3
  9. package/dist/{boot-reembed-f4nn561n.js → boot-reembed-k5y5xbj0.js} +15 -8
  10. package/dist/{boot-scrub-sweep-d4w9gajf.js → boot-scrub-sweep-se41j9fd.js} +3 -3
  11. package/dist/{boot-seeds-9bmkspyw.js → boot-seeds-r3kwwv8b.js} +4 -4
  12. package/dist/{claude-adapter-nys1kjxa.js → claude-adapter-ahmyf231.js} +8 -8
  13. package/dist/{claude-managed-adapter-55207973.js → claude-managed-adapter-5knamegc.js} +3 -3
  14. package/dist/{claude-managed-setup-3cm35gey.js → claude-managed-setup-mdc7dy6b.js} +3 -3
  15. package/dist/{claude-sdk-session-nw5yd8cp.js → claude-sdk-session-n5wen9zk.js} +8729 -8600
  16. package/dist/{cli-683y0b3a.js → cli-0dqtv2jg.js} +2 -2
  17. package/dist/{cli-a34pr3w1.js → cli-0tww7dnz.js} +2 -2
  18. package/dist/{cli-w2656ka1.js → cli-0w4e4v58.js} +7 -7
  19. package/dist/{cli-5sckpqcx.js → cli-2sjm3t4r.js} +1 -1
  20. package/dist/{cli-gf2850q7.js → cli-3cywb44q.js} +18 -1
  21. package/dist/{cli-8wkb09q5.js → cli-3k9jej0c.js} +2 -2
  22. package/dist/{cli-3aqd4jaa.js → cli-3v2cyqb8.js} +3 -3
  23. package/dist/{cli-emhjcj2y.js → cli-5qt9vzmq.js} +89 -20
  24. package/dist/{cli-abkm71vr.js → cli-5rp1w4cr.js} +1 -1
  25. package/dist/{cli-gf95q3bm.js → cli-6vwjsetx.js} +4 -4
  26. package/dist/{cli-k21gx5ht.js → cli-6w2yrrc0.js} +10 -10
  27. package/dist/{cli-m70bajzr.js → cli-75tdydgv.js} +1 -1
  28. package/dist/{cli-5rj83bam.js → cli-8feswf2v.js} +47 -36
  29. package/dist/{cli-sxgtf5fw.js → cli-8wd3mbyj.js} +1 -1
  30. package/dist/{cli-ca6banwz.js → cli-9csfthbw.js} +10 -8
  31. package/dist/{cli-dqygeeh5.js → cli-b41p764a.js} +31 -3
  32. package/dist/{cli-m5a9m0ak.js → cli-c1t533hh.js} +3 -3
  33. package/dist/{cli-2sjhpsns.js → cli-c28jxpcv.js} +1 -1
  34. package/dist/{cli-bqztfyve.js → cli-cb50g9cd.js} +1 -1
  35. package/dist/{cli-ag2yrnt5.js → cli-d8gaphtr.js} +2 -2
  36. package/dist/{cli-9abdgn5t.js → cli-dgtfysne.js} +3 -3
  37. package/dist/{cli-nq677csy.js → cli-dscnhn18.js} +1 -1
  38. package/dist/{cli-3fwqy71j.js → cli-dv11pgpv.js} +39 -32
  39. package/dist/{cli-v49fkghp.js → cli-ekptgk2m.js} +6 -6
  40. package/dist/{cli-c2habvsf.js → cli-f3mzy662.js} +17 -17
  41. package/dist/{cli-zqne1qcj.js → cli-fk7k8s9x.js} +2 -2
  42. package/dist/{cli-1tem6ns9.js → cli-gt4h8cxw.js} +3 -2
  43. package/dist/{cli-vbhgkw9h.js → cli-h3e7bhvn.js} +3 -3
  44. package/dist/{cli-ffvsj2qw.js → cli-hkxqdmnb.js} +3 -3
  45. package/dist/{cli-a2rr0fmg.js → cli-hpkvgdad.js} +7 -4
  46. package/dist/{cli-art7c1zh.js → cli-hq2v4rr5.js} +37 -9
  47. package/dist/{cli-sqma6vw1.js → cli-k1zb7raw.js} +5 -5
  48. package/dist/{cli-4rvr7zfx.js → cli-k4awgvzm.js} +5 -0
  49. package/dist/{cli-3ndmpxxv.js → cli-k7d3hvya.js} +2 -2
  50. package/dist/{cli-3gfvmzht.js → cli-kbtdftbw.js} +74 -26
  51. package/dist/{cli-hfeb68z4.js → cli-kj69b9tw.js} +34 -6
  52. package/dist/{cli-az25fn5f.js → cli-kk9jy4nm.js} +2 -2
  53. package/dist/{cli-39aet655.js → cli-m52t4cta.js} +1 -1
  54. package/dist/{cli-cz37jqss.js → cli-mdadewqp.js} +5 -5
  55. package/dist/{cli-esakngh8.js → cli-nf6k60sn.js} +1 -1
  56. package/dist/{cli-j6rktc91.js → cli-nzdf09js.js} +1 -1
  57. package/dist/{cli-rr7zx19j.js → cli-prcyzecg.js} +12 -12
  58. package/dist/{cli-4hxrf0p4.js → cli-pzafyqtk.js} +393 -62
  59. package/dist/{cli-g8ka5j4j.js → cli-qvaa1gjp.js} +173 -52
  60. package/dist/{cli-d2dpf95n.js → cli-rg4b2g6j.js} +1 -1
  61. package/dist/{cli-kf4jree9.js → cli-rm66vqdz.js} +1 -1
  62. package/dist/{cli-4rf0f5vg.js → cli-s504c3w7.js} +5 -3
  63. package/dist/{cli-nn6vx2mq.js → cli-swkx9jm2.js} +7 -5
  64. package/dist/{cli-g20jjwt4.js → cli-thsaq4pd.js} +16 -16
  65. package/dist/{cli-aj8djyqt.js → cli-twjnyvs8.js} +2 -2
  66. package/dist/{cli-03gg9pd1.js → cli-typdpe8g.js} +4 -4
  67. package/dist/{cli-mtnj4fwa.js → cli-vg8pwmsd.js} +6 -6
  68. package/dist/{cli-gnsb1zxa.js → cli-vhpckzvp.js} +1 -1
  69. package/dist/{cli-7enjwya9.js → cli-vz78s5wm.js} +1 -1
  70. package/dist/{cli-dv97kdzv.js → cli-wdxgsdz5.js} +2 -2
  71. package/dist/{cli-7a6p4e65.js → cli-wtjg6je3.js} +1 -1
  72. package/dist/{cli-6y51ryva.js → cli-x3cngb1h.js} +44 -12
  73. package/dist/{cli-n7asmce6.js → cli-xbz6mcg4.js} +3 -3
  74. package/dist/{cli-24j1jeeb.js → cli-y4tdxsqb.js} +3 -3
  75. package/dist/{cli-mvjz5an3.js → cli-yqrsp3ny.js} +7 -7
  76. package/dist/cli.js +31 -21
  77. package/dist/{codex-adapter-d95q4qsn.js → codex-adapter-7wepzq15.js} +6 -6
  78. package/dist/{codex-hook-brpnycn5.js → codex-hook-pbdh4xhx.js} +2 -2
  79. package/dist/{codex-session-runner-gdwd8h0c.js → codex-session-runner-02sb49e4.js} +6 -6
  80. package/dist/{commands-jqmgk54b.js → commands-3rcspxct.js} +2 -2
  81. package/dist/{controller-z3jq589f.js → controller-8ar4avd6.js} +3 -3
  82. package/dist/{controllers-connect-r2za39ef.js → controllers-connect-ajvh9h0v.js} +19 -19
  83. package/dist/{cursor-adapter-4mr4jgkw.js → cursor-adapter-gd0sa7bh.js} +1 -1
  84. package/dist/{db-w36wwb5g.js → db-dv9j7ts5.js} +2 -2
  85. package/dist/{db-ppv2tze7.js → db-z26vgdvj.js} +3 -3
  86. package/dist/{dispatcher-pv5h77vf.js → dispatcher-8m0htjq8.js} +17 -17
  87. package/dist/{dsh-adapter-d4pdpb3r.js → dsh-adapter-y8gyk130.js} +1 -1
  88. package/dist/{e2b-fn3zacvt.js → e2b-74vg9b7e.js} +1 -1
  89. package/dist/{e2b-222hsajc.js → e2b-jyay8wzn.js} +1 -1
  90. package/dist/{easter-egg-3d-4sp4dvmc.js → easter-egg-3d-28f880xx.js} +1 -1
  91. package/dist/{execute-jev839y1.js → execute-9seb79vh.js} +1 -1
  92. package/dist/{external-channel-y6nkzhnn.js → external-channel-smz7jyth.js} +2 -2
  93. package/dist/{getMachineId-bsd-brn0xym3.js → getMachineId-bsd-whfre6gr.js} +3 -3
  94. package/dist/{getMachineId-darwin-t339sfxm.js → getMachineId-darwin-5zjynb19.js} +3 -3
  95. package/dist/{getMachineId-linux-5eq95d8b.js → getMachineId-linux-8mksrrsq.js} +3 -3
  96. package/dist/{getMachineId-unsupported-qavrtc7j.js → getMachineId-unsupported-fxtqsdt2.js} +3 -3
  97. package/dist/{getMachineId-win-q7fe1wx7.js → getMachineId-win-nzfmz857.js} +3 -3
  98. package/dist/{grok-adapter-t08b9ntm.js → grok-adapter-z0nnvtbn.js} +7 -7
  99. package/dist/handlers-pspryh6g.js +41 -0
  100. package/dist/{heartbeat-vn31xwdk.js → heartbeat-f928aqyp.js} +20 -20
  101. package/dist/{hook-cpjs8q51.js → hook-d7c605r4.js} +7 -7
  102. package/dist/{hook-6d0zbvvt.js → hook-q9hv5xf9.js} +5 -5
  103. package/dist/{http-9c6medda.js → http-q6j4k989.js} +1000 -251
  104. package/dist/{index-k0yt1tvq.js → index-5nb266jr.js} +17 -17
  105. package/dist/{index-ysd45kgc.js → index-8fxt5eah.js} +10 -10
  106. package/dist/{index-zgvqzjsw.js → index-cekzwhez.js} +5 -5
  107. package/dist/{index-38t35h0n.js → index-ch0c1xff.js} +17 -17
  108. package/dist/{index-pkma1yf8.js → index-ebnjhxh1.js} +1 -1
  109. package/dist/{index-yqgbfgaj.js → index-ed8dy8rn.js} +20 -20
  110. package/dist/{index-qhjf2htm.js → index-ejqdkkqx.js} +262 -96
  111. package/dist/{index-dr94zbnh.js → index-farm1zsn.js} +32661 -29443
  112. package/dist/{index-g6k9tctj.js → index-yn1yxg85.js} +1 -1
  113. package/dist/{keepalive-em0117bp.js → keepalive-zzc3hks1.js} +3 -3
  114. package/dist/lead-c0pjcaw4.js +79 -0
  115. package/dist/{maintenance-kbme3qy9.js → maintenance-kqsxzpzx.js} +1 -1
  116. package/dist/{oauth-refresh-sweep-xysj4yse.js → oauth-refresh-sweep-7qt0g55z.js} +8 -3
  117. package/dist/{onboard-p6q0vz97.js → onboard-k7x13fqg.js} +121 -8
  118. package/dist/{opencode-adapter-esv3k9yn.js → opencode-adapter-tqvrtter.js} +5 -5
  119. package/dist/{otel-impl-54qhqh1z.js → otel-impl-sqkf6k3b.js} +97 -97
  120. package/dist/{pi-mono-adapter-mymbwhj0.js → pi-mono-adapter-m2qnafxm.js} +89 -14
  121. package/dist/{pricing-refresh-yb75wv33.js → pricing-refresh-wkpwhgvs.js} +3 -3
  122. package/dist/{rbac-roles-dexhc9x8.js → rbac-roles-dpn0c0wj.js} +7 -4
  123. package/dist/{rbac-roles-1vp2mw4p.js → rbac-roles-wk7xd6a6.js} +2 -2
  124. package/dist/{render-v2-tjay5hhf.js → render-v2-ex2m4g2k.js} +3 -3
  125. package/dist/{resume-8ayf37g5.js → resume-725g9b0b.js} +7 -7
  126. package/dist/{runtime-hqe5cqcd.js → runtime-kajas15g.js} +1 -1
  127. package/dist/{session-access-fdhp987s.js → session-access-0j2ezjje.js} +8 -4
  128. package/dist/{session-source-backfill-qgtc86z1.js → session-source-backfill-62202awe.js} +2 -2
  129. package/dist/{setup-4rrmqcq3.js → setup-9sj11ax6.js} +1 -1
  130. package/dist/{virtual-modules-52km00d6.js → virtual-modules-c6fcq6zr.js} +2 -2
  131. package/dist/{work-objects-p28fgd70.js → work-objects-0y07495y.js} +20 -20
  132. package/dist/worker-d4q9sqbc.js +79 -0
  133. package/openapi.json +1536 -407
  134. package/package.json +7 -5
  135. package/src/be/automation-preflight.ts +2 -0
  136. package/src/be/connector-codes.ts +65 -22
  137. package/src/be/db/api-keys.ts +9 -0
  138. package/src/be/db/workflow-runs.ts +36 -5
  139. package/src/be/db.ts +80 -22
  140. package/src/be/memory/boot-reembed.ts +4 -1
  141. package/src/be/memory/constants.ts +6 -0
  142. package/src/be/memory/embedding-recovery.ts +48 -0
  143. package/src/be/memory/index-content.ts +5 -2
  144. package/src/be/memory/providers/openai-embedding.ts +65 -14
  145. package/src/be/memory/task-learning.ts +257 -0
  146. package/src/be/memory/types.ts +13 -2
  147. package/src/be/migrations/245_script_executor.sql +3 -0
  148. package/src/be/migrations/246_connector_code_kind.sql +11 -0
  149. package/src/be/oauth-refresh-sweep.ts +2 -1
  150. package/src/be/onboarding.ts +125 -15
  151. package/src/be/rbac-roles.ts +4 -1
  152. package/src/be/scripts/boot-reembed.ts +2 -0
  153. package/src/be/scripts/db.ts +14 -4
  154. package/src/be/scripts/embeddings.ts +4 -2
  155. package/src/be/scripts/run-saved.ts +1 -0
  156. package/src/be/scripts/typecheck.ts +9 -3
  157. package/src/be/seed/agent-fs-provision.ts +75 -14
  158. package/src/be/seed-skills/index.ts +7 -0
  159. package/src/be/swarm-config-guard.ts +3 -0
  160. package/src/cli.tsx +9 -0
  161. package/src/comb/config.ts +6 -1
  162. package/src/commands/onboard/agent-fs-version.ts +5 -0
  163. package/src/commands/onboard/compose-generator.ts +117 -4
  164. package/src/commands/onboard/env-generator.ts +9 -0
  165. package/src/commands/onboard/tei-image.ts +12 -0
  166. package/src/commands/onboard/types.ts +7 -0
  167. package/src/commands/onboard.tsx +11 -1
  168. package/src/commands/provider-credentials.ts +2 -1
  169. package/src/commands/runner.ts +14 -1
  170. package/src/heartbeat/heartbeat.ts +14 -1
  171. package/src/heartbeat/script-runner-probe.ts +47 -0
  172. package/src/http/agentfs-proxy.ts +369 -0
  173. package/src/http/all-routes.ts +1 -0
  174. package/src/http/api-keys.ts +24 -9
  175. package/src/http/codex-oauth-device.ts +8 -1
  176. package/src/http/fs.ts +64 -10
  177. package/src/http/idempotency-key.ts +1 -1
  178. package/src/http/inbox-state.ts +27 -1
  179. package/src/http/index.ts +7 -4
  180. package/src/http/memory.ts +7 -4
  181. package/src/http/onboarding.ts +139 -11
  182. package/src/http/pages-public.ts +38 -5
  183. package/src/http/scripts.ts +27 -0
  184. package/src/http/session-access.ts +24 -0
  185. package/src/http/sessions.ts +10 -6
  186. package/src/http/tasks.ts +85 -11
  187. package/src/http/telemetry-ui.ts +1 -1
  188. package/src/http/user-roles.ts +4 -1
  189. package/src/http/users.ts +272 -3
  190. package/src/http/utils.ts +22 -3
  191. package/src/http/workflows.ts +10 -0
  192. package/src/http/x.ts +5 -0
  193. package/src/prompts/base-prompt.ts +45 -10
  194. package/src/prompts/session-templates.ts +43 -5
  195. package/src/providers/amp-adapter.ts +1 -1
  196. package/src/providers/codex-adapter.ts +6 -1
  197. package/src/providers/cursor-adapter.ts +1 -1
  198. package/src/providers/dsh-adapter.ts +1 -1
  199. package/src/providers/pi-mono-adapter.ts +99 -14
  200. package/src/rbac/legacy-policy.ts +1 -0
  201. package/src/rbac/permissions.ts +4 -0
  202. package/src/scheduler/scheduler.ts +2 -1
  203. package/src/scripts-runtime/eval-harness.ts +8 -1
  204. package/src/scripts-runtime/executors/native.ts +22 -16
  205. package/src/scripts-runtime/executors/quickjs-prelude.ts +103 -1
  206. package/src/scripts-runtime/executors/quickjs-runner.ts +2 -1
  207. package/src/scripts-runtime/executors/quickjs.ts +7 -0
  208. package/src/scripts-runtime/executors/registry.ts +32 -0
  209. package/src/scripts-runtime/executors/types.ts +7 -0
  210. package/src/scripts-runtime/host-validated-args.ts +133 -0
  211. package/src/scripts-runtime/loader.ts +30 -3
  212. package/src/scripts-runtime/swarm-sdk.ts +9 -2
  213. package/src/scripts-runtime/types/stdlib.d.ts +9 -1
  214. package/src/scripts-runtime/types/swarm-sdk.d.ts +9 -1
  215. package/src/tests/agent-fs-provision-seeder.test.ts +261 -92
  216. package/src/tests/agentfs-proxy.test.ts +1106 -0
  217. package/src/tests/api-key-status-by-suffix.test.ts +242 -0
  218. package/src/tests/base-prompt.test.ts +139 -4
  219. package/src/tests/codex-adapter.test.ts +46 -8
  220. package/src/tests/codex-oauth-device.test.ts +12 -1
  221. package/src/tests/comb-config-guard.test.ts +20 -0
  222. package/src/tests/comb-links.test.ts +79 -1
  223. package/src/tests/comb-status.test.ts +44 -0
  224. package/src/tests/community-linear-delivery-loop.test.ts +2099 -0
  225. package/src/tests/credential-check.test.ts +4 -2
  226. package/src/tests/docs-index-footprint.test.js +3 -3
  227. package/src/tests/docs-index.test.ts +135 -0
  228. package/src/tests/dsh-adapter.test.ts +1 -1
  229. package/src/tests/fetch-resolved-env.test.ts +16 -2
  230. package/src/tests/fixtures/onboard/baseline-states.ts +68 -0
  231. package/src/tests/fixtures/onboard/content.compose.yml.txt +190 -0
  232. package/src/tests/fixtures/onboard/content.env.txt +29 -0
  233. package/src/tests/fixtures/onboard/dev.compose.yml.txt +155 -0
  234. package/src/tests/fixtures/onboard/dev.env.txt +28 -0
  235. package/src/tests/fixtures/onboard/full-all.compose.yml.txt +582 -0
  236. package/src/tests/fixtures/onboard/full-all.env.txt +59 -0
  237. package/src/tests/fixtures/onboard/full.compose.yml.txt +435 -0
  238. package/src/tests/fixtures/onboard/full.env.txt +36 -0
  239. package/src/tests/fixtures/onboard/research.compose.yml.txt +155 -0
  240. package/src/tests/fixtures/onboard/research.env.txt +28 -0
  241. package/src/tests/fixtures/onboard/solo.compose.yml.txt +85 -0
  242. package/src/tests/fixtures/onboard/solo.env.txt +26 -0
  243. package/src/tests/heartbeat-checklist.test.ts +89 -0
  244. package/src/tests/heartbeat-script-runner-probe.test.ts +83 -0
  245. package/src/tests/http-log-scrubbing.test.ts +34 -1
  246. package/src/tests/http-task-write-ownership.test.ts +5 -1
  247. package/src/tests/invites-http.test.ts +464 -0
  248. package/src/tests/memory-embedding-input-cap.test.ts +122 -1
  249. package/src/tests/memory-embedding-recovery.test.ts +137 -0
  250. package/src/tests/oauth-refresh-sweep.test.ts +34 -1
  251. package/src/tests/onboard-compose.test.ts +162 -0
  252. package/src/tests/onboard-env.test.ts +24 -0
  253. package/src/tests/onboard-non-interactive.test.ts +29 -0
  254. package/src/tests/onboard-tei-image.test.ts +36 -0
  255. package/src/tests/onboarding.test.ts +451 -4
  256. package/src/tests/openai-embedding-provider.test.ts +105 -2
  257. package/src/tests/opencode-adapter.test.ts +2 -1
  258. package/src/tests/pages-frame-ancestors.test.ts +162 -0
  259. package/src/tests/pi-codemode.test.ts +2 -1
  260. package/src/tests/pi-mono-adapter.test.ts +54 -0
  261. package/src/tests/pi-mono-session-cost-on-abort.test.ts +270 -0
  262. package/src/tests/pi-native-mcp.test.ts +13 -1
  263. package/src/tests/pi-tool-exposure.test.ts +8 -8
  264. package/src/tests/preload-env.test.ts +4 -0
  265. package/src/tests/preload.ts +4 -0
  266. package/src/tests/probe-tool-schema-tokens.test.ts +144 -0
  267. package/src/tests/prompt-template-session.test.ts +20 -3
  268. package/src/tests/rbac-admission-e2e.test.ts +22 -6
  269. package/src/tests/rbac-admission.test.ts +342 -4
  270. package/src/tests/rbac-engine.test.ts +1 -0
  271. package/src/tests/rbac-roles.test.ts +9 -1
  272. package/src/tests/request-composition-derive.test.ts +329 -0
  273. package/src/tests/script-connections.test.ts +2 -0
  274. package/src/tests/script-executor-conformance.test.ts +36 -1
  275. package/src/tests/script-executor-quickjs-pool.test.ts +50 -0
  276. package/src/tests/script-executor-quickjs.test.ts +140 -0
  277. package/src/tests/script-host-validated-args-native.test.ts +196 -0
  278. package/src/tests/script-per-script-executor.test.ts +415 -0
  279. package/src/tests/scripts-external-api.test.ts +45 -0
  280. package/src/tests/sdk-allowlist.test.ts +3 -2
  281. package/src/tests/self-improvement.test.ts +4 -4
  282. package/src/tests/send-task-requester-gate.test.ts +64 -3
  283. package/src/tests/sessions-move.test.ts +39 -1
  284. package/src/tests/store-progress-learning.test.ts +381 -0
  285. package/src/tests/ui-logs-parser.test.ts +180 -0
  286. package/src/tests/whoami-route.test.ts +41 -0
  287. package/src/tests/workflow-engine-v2.test.ts +116 -1
  288. package/src/tests/workflow-mcp-trigger-schema.test.ts +209 -0
  289. package/src/tests/workflow-run-finished-event.test.ts +263 -0
  290. package/src/tests/workflow-swarm-script.test.ts +34 -0
  291. package/src/tools/inject-learning.ts +1 -1
  292. package/src/tools/memory-edit.ts +1 -1
  293. package/src/tools/memory-search.ts +1 -1
  294. package/src/tools/script-common.ts +1 -0
  295. package/src/tools/script-run.ts +7 -0
  296. package/src/tools/script-upsert.ts +7 -0
  297. package/src/tools/store-progress.ts +71 -1
  298. package/src/tools/utils.ts +12 -1
  299. package/src/tools/workflows/trigger-workflow.ts +104 -10
  300. package/src/types.ts +12 -1
  301. package/src/utils/constants.ts +39 -0
  302. package/src/utils/credentials.ts +5 -2
  303. package/src/utils/task-attachment-links.ts +15 -3
  304. package/src/workflows/engine.ts +18 -16
  305. package/src/workflows/executors/swarm-script.ts +5 -0
  306. package/src/workflows/foreach-driver.ts +5 -11
  307. package/src/workflows/node-timeout.ts +30 -0
  308. package/templates/community/linear-delivery-loop/PLAYBOOK.md +323 -0
  309. package/templates/community/linear-delivery-loop/README.md +38 -0
  310. package/templates/community/linear-delivery-loop/config.example.json +31 -0
  311. package/templates/community/linear-delivery-loop/lead-prompt.md +34 -0
  312. package/templates/community/linear-delivery-loop/schedule.json +10 -0
  313. package/templates/community/linear-delivery-loop/scripts/linear-delivery-setup.ts +148 -0
  314. package/templates/community/linear-delivery-loop/scripts/linear-delivery-tick.ts +1781 -0
  315. package/templates/skills/swarm-docs/config.json +14 -0
  316. package/templates/skills/swarm-docs/content.md +144 -0
  317. package/dist/handlers-eqsnmv95.js +0 -41
  318. package/dist/lead-23e7z59t.js +0 -79
  319. package/dist/worker-e3w7vye1.js +0 -79
  320. package/dist/{azure-openai-responses-9kfwhmn7.js → azure-openai-responses-43asa23s.js} +0 -0
  321. package/dist/{node-vxx896fa.js → node-t28cc56b.js} +0 -0
  322. package/dist/{openai-codex-responses-79s8xnbh.js → openai-codex-responses-jhr3sjtm.js} +3 -3
  323. package/dist/{openai-completions-tdbyts0x.js → openai-completions-gs6yn37k.js} +3 -3
  324. /package/dist/{openai-responses-dm3t5vqp.js → openai-responses-jqm9vwwk.js} +0 -0
@@ -1323,10 +1323,12 @@ describe("NaN and Helmcode live probes", () => {
1323
1323
  // ─── Migration 055: report composition + opt-out ────────────────────────────
1324
1324
 
1325
1325
  describe("isCredCheckDisabled", () => {
1326
- test("true only when CRED_CHECK_DISABLE === '1'", () => {
1326
+ test("true when CRED_CHECK_DISABLE is '1' or 'true' (case-insensitive)", () => {
1327
1327
  expect(isCredCheckDisabled({})).toBe(false);
1328
1328
  expect(isCredCheckDisabled({ CRED_CHECK_DISABLE: "0" })).toBe(false);
1329
- expect(isCredCheckDisabled({ CRED_CHECK_DISABLE: "true" })).toBe(false);
1329
+ expect(isCredCheckDisabled({ CRED_CHECK_DISABLE: "false" })).toBe(false);
1330
+ expect(isCredCheckDisabled({ CRED_CHECK_DISABLE: "true" })).toBe(true);
1331
+ expect(isCredCheckDisabled({ CRED_CHECK_DISABLE: "TRUE" })).toBe(true);
1330
1332
  expect(isCredCheckDisabled({ CRED_CHECK_DISABLE: "1" })).toBe(true);
1331
1333
  });
1332
1334
  });
@@ -78,7 +78,7 @@ describe("docs API index footprint", () => {
78
78
  expect(tasks).toContain('"path":"/api/task-templates","method":"get"');
79
79
  });
80
80
 
81
- test("OpenAPI and generated pages keep all 456 operations", async () => {
81
+ test("OpenAPI and generated pages keep all 466 operations", async () => {
82
82
  const spec = await Bun.file(resolve(repoRoot, "openapi.json")).json();
83
83
  const operationKeys = [];
84
84
  const tags = new Set();
@@ -103,8 +103,8 @@ describe("docs API index footprint", () => {
103
103
  expect(spec.paths["/api/agents/{id}/runtime"]?.get).toBeDefined();
104
104
 
105
105
  const generatedKeys = await generatedOperationKeys();
106
- expect(operationKeys).toHaveLength(456);
107
- expect(generatedKeys).toHaveLength(456);
106
+ expect(operationKeys).toHaveLength(466);
107
+ expect(generatedKeys).toHaveLength(466);
108
108
  expect(new Set(generatedKeys)).toEqual(new Set(operationKeys));
109
109
  });
110
110
 
@@ -0,0 +1,135 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
+ import { mkdir, mkdtemp, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import {
6
+ collectDocsPages,
7
+ coverageErrors,
8
+ INDEX_END,
9
+ INDEX_START,
10
+ renderDocsIndex,
11
+ replaceIndexBlock,
12
+ SKILL_CONTENT_PATH,
13
+ } from "../../scripts/build-docs-index";
14
+ import { loadSeedSkills } from "../be/seed-skills";
15
+
16
+ const page = (frontmatter: string, body = "Body.\n") => `---\n${frontmatter}\n---\n\n${body}`;
17
+
18
+ describe("docs index (real docs tree)", () => {
19
+ test("every playbook is in the index and the coverage rules pass", async () => {
20
+ const pages = await collectDocsPages();
21
+ expect(coverageErrors(pages)).toEqual([]);
22
+
23
+ const index = renderDocsIndex(pages);
24
+ const playbooks = pages.filter((p) => p.path.startsWith("playbooks/"));
25
+ expect(playbooks.length).toBeGreaterThan(10);
26
+ for (const playbook of playbooks) {
27
+ expect(index).toContain(`(https://docs.agent-swarm.dev/docs/${playbook.slug})`);
28
+ }
29
+ // Positive control: a known playbook carries its trigger.
30
+ expect(index).toContain(
31
+ "[Open Oncall](https://docs.agent-swarm.dev/docs/playbooks/open-oncall). When: ",
32
+ );
33
+ // Negative control: opted-out pages are reference only, release notes are skipped.
34
+ expect(index).toContain("(https://docs.agent-swarm.dev/docs/playbooks). Reference.");
35
+ expect(index).not.toContain("/docs/releases/");
36
+ });
37
+
38
+ test("the committed skill body matches the generator", async () => {
39
+ const content = await Bun.file(SKILL_CONTENT_PATH).text();
40
+ const regenerated = replaceIndexBlock(content, renderDocsIndex(await collectDocsPages()));
41
+ expect(content).toBe(regenerated);
42
+ });
43
+
44
+ test("the generator is deterministic", async () => {
45
+ const first = renderDocsIndex(await collectDocsPages());
46
+ const second = renderDocsIndex(await collectDocsPages());
47
+ expect(second).toBe(first);
48
+ });
49
+
50
+ test("the seeded skill is a system default and carries the index", async () => {
51
+ const skill = (await loadSeedSkills()).find((s) => s.name === "swarm-docs");
52
+ expect(skill?.systemDefault).toBe(true);
53
+ expect(skill?.content).toContain("https://docs.agent-swarm.dev/docs/playbooks/open-oncall");
54
+ });
55
+ });
56
+
57
+ describe("docs index (fixture tree)", () => {
58
+ let root: string;
59
+
60
+ beforeAll(async () => {
61
+ root = await mkdtemp(join(tmpdir(), "docs-index-"));
62
+ await mkdir(join(root, "playbooks"), { recursive: true });
63
+ await mkdir(join(root, "guides"), { recursive: true });
64
+ await mkdir(join(root, "releases"), { recursive: true });
65
+ await Bun.write(join(root, "meta.json"), JSON.stringify({ pages: ["index", "playbooks"] }));
66
+ await Bun.write(join(root, "index.mdx"), page("title: Home"));
67
+ await Bun.write(
68
+ join(root, "playbooks", "meta.json"),
69
+ JSON.stringify({ pages: ["index", "b", "---Separator---", "a"] }),
70
+ );
71
+ await Bun.write(
72
+ join(root, "playbooks", "index.mdx"),
73
+ page("title: Playbooks\nagent:\n offer: false"),
74
+ );
75
+ await Bun.write(
76
+ join(root, "playbooks", "a.mdx"),
77
+ page('title: A\nagent:\n when: "Someone wants A"\n template: "community/a"'),
78
+ );
79
+ await Bun.write(join(root, "playbooks", "b.mdx"), page("title: B"));
80
+ await Bun.write(
81
+ join(root, "guides", "g.mdx"),
82
+ page("title: G\nagent:\n offer: true\n notWhen: never"),
83
+ );
84
+ await Bun.write(join(root, "releases", "r.mdx"), page("title: R"));
85
+ });
86
+
87
+ afterAll(async () => {
88
+ await rm(root, { recursive: true, force: true });
89
+ });
90
+
91
+ test("orders by meta.json, appends unlisted folders, and skips releases", async () => {
92
+ const pages = await collectDocsPages(root);
93
+ expect(pages.map((p) => p.path)).toEqual([
94
+ "index",
95
+ "playbooks/index",
96
+ "playbooks/b",
97
+ "playbooks/a",
98
+ "guides/g",
99
+ ]);
100
+ expect(pages.map((p) => p.slug)).toEqual([
101
+ "",
102
+ "playbooks",
103
+ "playbooks/b",
104
+ "playbooks/a",
105
+ "guides/g",
106
+ ]);
107
+ });
108
+
109
+ test("a playbook without when, and an offered guide without when, fail coverage", async () => {
110
+ const errors = coverageErrors(await collectDocsPages(root));
111
+ expect(errors).toEqual([
112
+ "playbooks/b: playbook needs agent.when (or agent.offer: false)",
113
+ "guides/g: agent.offer is true but agent.when is missing",
114
+ ]);
115
+ });
116
+
117
+ test("renders triggers and templates for offered pages only", async () => {
118
+ const index = renderDocsIndex(await collectDocsPages(root));
119
+ expect(index).toContain(
120
+ "- [A](https://docs.agent-swarm.dev/docs/playbooks/a). When: Someone wants A. Template: `community/a`.",
121
+ );
122
+ expect(index).toContain(
123
+ "- [Playbooks](https://docs.agent-swarm.dev/docs/playbooks). Reference.",
124
+ );
125
+ expect(index).toContain("- [Home](https://docs.agent-swarm.dev/docs)");
126
+ });
127
+
128
+ test("replaceIndexBlock swaps only the marked block and rejects missing markers", () => {
129
+ const content = `before\n${INDEX_START}\nold\n${INDEX_END}\nafter\n`;
130
+ expect(replaceIndexBlock(content, `${INDEX_START}\nnew\n${INDEX_END}`)).toBe(
131
+ `before\n${INDEX_START}\nnew\n${INDEX_END}\nafter\n`,
132
+ );
133
+ expect(() => replaceIndexBlock("no markers", "x")).toThrow();
134
+ });
135
+ });
@@ -376,7 +376,7 @@ describe("dsh harness", () => {
376
376
  await rename(join(config.cwd, "dsh"), join(config.cwd, "npx"));
377
377
  config.env = { ...config.env, DSH_BINARY: "", PATH: config.cwd };
378
378
  await expect(new DshAdapter().createSession(config)).rejects.toThrow(
379
- "dsh CLI not found. Install @deepseek-ai/dsh@0.2.1-rc.3",
379
+ "dsh CLI not found. Install @deepseek-ai/dsh@0.2.1-rc.4",
380
380
  );
381
381
  expect(await Bun.file(join(config.cwd, "invocation.json")).exists()).toBe(false);
382
382
  });
@@ -41,8 +41,12 @@ const defaultMockResponse: MockResponse = {
41
41
  const mockResponsesByAgentId = new Map<string, MockResponse>();
42
42
  const requestedRepoIds = new Map<string, string | null>();
43
43
  const requestedTaskIds = new Map<string, string | null>();
44
- /** Every `GET /api/keys/available` query string observed by the mock server, most recent last. */
44
+ /**
45
+ * Every `GET /api/keys/available` query string observed by the mock server,
46
+ * most recent last, without `keySuffixes` (recorded in `keysAvailableSuffixes`).
47
+ */
45
48
  const keysAvailableRequests: string[] = [];
49
+ const keysAvailableSuffixes: Array<string | null> = [];
46
50
 
47
51
  beforeAll(() => {
48
52
  server = Bun.serve({
@@ -63,7 +67,10 @@ beforeAll(() => {
63
67
  }
64
68
 
65
69
  if (url.pathname === "/api/keys/available") {
66
- keysAvailableRequests.push(url.search);
70
+ const params = new URLSearchParams(url.search);
71
+ keysAvailableSuffixes.push(params.get("keySuffixes"));
72
+ params.delete("keySuffixes");
73
+ keysAvailableRequests.push(`?${params}`);
67
74
  const totalKeys = Number(url.searchParams.get("totalKeys") ?? "1");
68
75
  const availableIndices = Array.from({ length: totalKeys }, (_, i) => i);
69
76
  return Response.json({ success: true, availableIndices, totalKeys });
@@ -455,6 +462,13 @@ describe("fetchResolvedEnv", () => {
455
462
  expect(keysAvailableRequests).toEqual([
456
463
  "?keyType=CLAUDE_CODE_OAUTH_TOKEN&totalKeys=32&model=fable",
457
464
  ]);
465
+ // The pool's own suffixes, in order, so status is matched by key (issue #2425).
466
+ expect(keysAvailableSuffixes.at(-1)).toBe(
467
+ Object.values(envWithOauthPool(32))[0]!
468
+ .split(",")
469
+ .map((key) => key.slice(-5))
470
+ .join(","),
471
+ );
458
472
  });
459
473
 
460
474
  test("model: 'claude-fable-5-1' issues the same model=fable", async () => {
@@ -0,0 +1,68 @@
1
+ import { getPresetById } from "../../../commands/onboard/presets.ts";
2
+ import { INITIAL_STATE, type OnboardState } from "../../../commands/onboard/types.ts";
3
+
4
+ /**
5
+ * Deterministic onboard states, one per unattended preset plus one variant
6
+ * with every integration, Bedrock (profile) and Podman. The fixtures next to
7
+ * this file hold the compose and .env these states rendered before the
8
+ * agent-fs bundle existed, so flag-off output stays byte-identical.
9
+ */
10
+ export const BASELINE_PRESET_IDS = ["full", "dev", "content", "research", "solo"] as const;
11
+
12
+ function agentIdsFor(state: Pick<OnboardState, "services">): Record<string, string> {
13
+ const ids: Record<string, string> = {};
14
+ let n = 0;
15
+ const next = () => `00000000-0000-4000-8000-${String(++n).padStart(12, "0")}`;
16
+ for (const svc of state.services) {
17
+ if (svc.count === 1) {
18
+ ids[svc.isLead ? "lead" : `worker-${svc.role}`] = next();
19
+ } else {
20
+ for (let i = 1; i <= svc.count; i++) ids[`worker-${svc.role}-${i}`] = next();
21
+ }
22
+ }
23
+ return ids;
24
+ }
25
+
26
+ export function baselineState(presetId: string, variant: "default" | "all" = "default") {
27
+ const preset = getPresetById(presetId);
28
+ if (!preset) throw new Error(`unknown preset ${presetId}`);
29
+ const base: OnboardState = {
30
+ ...INITIAL_STATE,
31
+ nonInteractive: true,
32
+ presetId: preset.id,
33
+ services: preset.services,
34
+ apiKey: "example-test-api-key",
35
+ claudeOAuthToken: "example-test-oauth",
36
+ outputDir: "/tmp/onboard-fixture",
37
+ };
38
+ base.agentIds = agentIdsFor(base);
39
+ if (variant === "default") return base;
40
+ return {
41
+ ...base,
42
+ provider: "bedrock",
43
+ harness: "pi",
44
+ awsRegion: "us-east-1",
45
+ awsProfile: "example-profile",
46
+ modelOverride: "example-model",
47
+ containerEngine: "podman",
48
+ pullPolicy: "missing",
49
+ apiPort: 3999,
50
+ maxConcurrentTasks: 3,
51
+ integrations: { github: true, slack: true, gitlab: true, sentry: true },
52
+ githubToken: "example-gh",
53
+ githubEmail: "dev@example.com",
54
+ githubName: "Example Dev",
55
+ slackBotToken: "example-slack-bot",
56
+ slackSigningSecret: "example-slack-signing",
57
+ slackMode: "http",
58
+ gitlabToken: "example-gitlab",
59
+ gitlabEmail: "dev@example.com",
60
+ sentryToken: "example-sentry",
61
+ sentryOrg: "example-org",
62
+ } satisfies OnboardState;
63
+ }
64
+
65
+ export const BASELINE_CASES: { name: string; state: OnboardState }[] = [
66
+ ...BASELINE_PRESET_IDS.map((id) => ({ name: id, state: baselineState(id) })),
67
+ { name: "full-all", state: baselineState("full", "all") },
68
+ ];
@@ -0,0 +1,190 @@
1
+ # Docker Compose for Agent Swarm
2
+ # Generated by `agent-swarm onboard`
3
+ #
4
+ # Usage:
5
+ # docker compose --env-file .env up -d
6
+ #
7
+ # Image version: set AGENT_SWARM_VERSION in .env to a published release.
8
+ # Blank falls back to `latest`, which moves on every commit to main and is
9
+ # not a release. Releases: https://github.com/desplega-ai/agent-swarm/releases
10
+ # Upgrade/rollback (migrations are forward-only, so back up first):
11
+ # https://github.com/desplega-ai/agent-swarm/blob/main/skills/agent-swarm/references/upgrade.md
12
+
13
+ services:
14
+ swarm-api:
15
+ image: "ghcr.io/desplega-ai/agent-swarm:${AGENT_SWARM_VERSION:-latest}"
16
+ container_name: swarm-api
17
+ pull_policy: always
18
+ stop_grace_period: 60s
19
+
20
+ environment:
21
+ - API_KEY=${API_KEY}
22
+ - INSTALL_METHOD=${INSTALL_METHOD}
23
+ - INSTALL_PRESET=${INSTALL_PRESET:-}
24
+ - MEMORY_HYBRID_SEARCH=${MEMORY_HYBRID_SEARCH-1}
25
+ - MEMORY_GRAPH_EXPANSION=${MEMORY_GRAPH_EXPANSION-1}
26
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
27
+ - MEMORY_DEMOTION_FLOOR=${MEMORY_DEMOTION_FLOOR-1.0}
28
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
29
+ - MCP_BASE_URL=http://localhost:3013
30
+ - APP_URL=https://app.agent-swarm.dev
31
+
32
+ ports:
33
+ - "3013:3013"
34
+
35
+ volumes:
36
+ - swarm_data:/app/data
37
+
38
+ healthcheck:
39
+ test: ["CMD-SHELL", "curl -f http://localhost:3013/health || exit 1"]
40
+ interval: 10s
41
+ timeout: 5s
42
+ retries: 3
43
+ start_period: 15s
44
+
45
+ restart: unless-stopped
46
+
47
+ lead:
48
+ image: "ghcr.io/desplega-ai/agent-swarm-worker:${AGENT_SWARM_VERSION:-latest}"
49
+ container_name: swarm-lead
50
+ pull_policy: always
51
+ stop_grace_period: 60s
52
+
53
+ depends_on:
54
+ swarm-api:
55
+ condition: service_healthy
56
+
57
+ environment:
58
+ - HARNESS_PROVIDER=${HARNESS_PROVIDER}
59
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
60
+ - API_KEY=${API_KEY}
61
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
62
+ - AGENT_ID=00000000-0000-4000-8000-000000000001
63
+ - AGENT_NAME=Lead
64
+ - AGENT_ROLE=lead
65
+ - TEMPLATE_ID=official/lead
66
+ - MCP_BASE_URL=http://swarm-api:3013
67
+ - YOLO=true
68
+ - SWARM_URL=http://swarm-api:3013
69
+ - MAX_CONCURRENT_TASKS=2
70
+
71
+ ports:
72
+ - "3201:3000"
73
+
74
+ volumes:
75
+ - swarm_logs:/logs
76
+ - swarm_shared:/workspace/shared
77
+ - swarm_lead:/workspace/personal
78
+
79
+ restart: unless-stopped
80
+
81
+ worker-content-writer:
82
+ image: "ghcr.io/desplega-ai/agent-swarm-worker:${AGENT_SWARM_VERSION:-latest}"
83
+ container_name: swarm-worker-content-writer
84
+ pull_policy: always
85
+ stop_grace_period: 60s
86
+
87
+ depends_on:
88
+ swarm-api:
89
+ condition: service_healthy
90
+
91
+ environment:
92
+ - HARNESS_PROVIDER=${HARNESS_PROVIDER}
93
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
94
+ - API_KEY=${API_KEY}
95
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
96
+ - AGENT_ID=00000000-0000-4000-8000-000000000002
97
+ - AGENT_NAME=Content Writer
98
+ - AGENT_ROLE=worker
99
+ - TEMPLATE_ID=official/content-writer
100
+ - MCP_BASE_URL=http://swarm-api:3013
101
+ - YOLO=true
102
+ - SWARM_URL=http://swarm-api:3013
103
+ - MAX_CONCURRENT_TASKS=1
104
+
105
+ ports:
106
+ - "3202:3000"
107
+
108
+ volumes:
109
+ - swarm_logs:/logs
110
+ - swarm_shared:/workspace/shared
111
+ - swarm_worker_content_writer:/workspace/personal
112
+
113
+ restart: unless-stopped
114
+
115
+ worker-content-reviewer:
116
+ image: "ghcr.io/desplega-ai/agent-swarm-worker:${AGENT_SWARM_VERSION:-latest}"
117
+ container_name: swarm-worker-content-reviewer
118
+ pull_policy: always
119
+ stop_grace_period: 60s
120
+
121
+ depends_on:
122
+ swarm-api:
123
+ condition: service_healthy
124
+
125
+ environment:
126
+ - HARNESS_PROVIDER=${HARNESS_PROVIDER}
127
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
128
+ - API_KEY=${API_KEY}
129
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
130
+ - AGENT_ID=00000000-0000-4000-8000-000000000003
131
+ - AGENT_NAME=Content Reviewer
132
+ - AGENT_ROLE=worker
133
+ - TEMPLATE_ID=official/content-reviewer
134
+ - MCP_BASE_URL=http://swarm-api:3013
135
+ - YOLO=true
136
+ - SWARM_URL=http://swarm-api:3013
137
+ - MAX_CONCURRENT_TASKS=1
138
+
139
+ ports:
140
+ - "3203:3000"
141
+
142
+ volumes:
143
+ - swarm_logs:/logs
144
+ - swarm_shared:/workspace/shared
145
+ - swarm_worker_content_reviewer:/workspace/personal
146
+
147
+ restart: unless-stopped
148
+
149
+ worker-content-strategist:
150
+ image: "ghcr.io/desplega-ai/agent-swarm-worker:${AGENT_SWARM_VERSION:-latest}"
151
+ container_name: swarm-worker-content-strategist
152
+ pull_policy: always
153
+ stop_grace_period: 60s
154
+
155
+ depends_on:
156
+ swarm-api:
157
+ condition: service_healthy
158
+
159
+ environment:
160
+ - HARNESS_PROVIDER=${HARNESS_PROVIDER}
161
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
162
+ - API_KEY=${API_KEY}
163
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
164
+ - AGENT_ID=00000000-0000-4000-8000-000000000004
165
+ - AGENT_NAME=Content Strategist
166
+ - AGENT_ROLE=worker
167
+ - TEMPLATE_ID=official/content-strategist
168
+ - MCP_BASE_URL=http://swarm-api:3013
169
+ - YOLO=true
170
+ - SWARM_URL=http://swarm-api:3013
171
+ - MAX_CONCURRENT_TASKS=1
172
+
173
+ ports:
174
+ - "3204:3000"
175
+
176
+ volumes:
177
+ - swarm_logs:/logs
178
+ - swarm_shared:/workspace/shared
179
+ - swarm_worker_content_strategist:/workspace/personal
180
+
181
+ restart: unless-stopped
182
+
183
+ volumes:
184
+ swarm_data:
185
+ swarm_logs:
186
+ swarm_shared:
187
+ swarm_lead:
188
+ swarm_worker_content_writer:
189
+ swarm_worker_content_reviewer:
190
+ swarm_worker_content_strategist:
@@ -0,0 +1,29 @@
1
+ # === Core ===
2
+ API_KEY=example-test-api-key
3
+ MCP_BASE_URL=http://localhost:3013
4
+ APP_URL=https://app.agent-swarm.dev
5
+ # Pin a release, e.g. AGENT_SWARM_VERSION=1.150.0. Blank tracks `latest`.
6
+ AGENT_SWARM_VERSION=
7
+ INSTALL_METHOD=onboard_noninteractive
8
+ INSTALL_PRESET=content
9
+
10
+ # New-deployment memory preset: retrieval, citation ratings, self-rating hints.
11
+ # Set MEMORY_RATERS= to disable all raters; leave SKIP_SESSION_SUMMARY unset.
12
+ MEMORY_HYBRID_SEARCH=1
13
+ MEMORY_GRAPH_EXPANSION=1
14
+ MEMORY_RATERS=implicit-citation,explicit-self
15
+ MEMORY_DEMOTION_FLOOR=1.0
16
+
17
+ # === Authentication ===
18
+ HARNESS_PROVIDER=claude
19
+ CLAUDE_CODE_OAUTH_TOKEN=example-test-oauth
20
+
21
+ # === Integrations ===
22
+ GITHUB_DISABLE=true
23
+ SLACK_DISABLE=true
24
+
25
+ # === Agent IDs (for reference) ===
26
+ # lead = 00000000-0000-4000-8000-000000000001
27
+ # worker-content-writer = 00000000-0000-4000-8000-000000000002
28
+ # worker-content-reviewer = 00000000-0000-4000-8000-000000000003
29
+ # worker-content-strategist = 00000000-0000-4000-8000-000000000004
@@ -0,0 +1,155 @@
1
+ # Docker Compose for Agent Swarm
2
+ # Generated by `agent-swarm onboard`
3
+ #
4
+ # Usage:
5
+ # docker compose --env-file .env up -d
6
+ #
7
+ # Image version: set AGENT_SWARM_VERSION in .env to a published release.
8
+ # Blank falls back to `latest`, which moves on every commit to main and is
9
+ # not a release. Releases: https://github.com/desplega-ai/agent-swarm/releases
10
+ # Upgrade/rollback (migrations are forward-only, so back up first):
11
+ # https://github.com/desplega-ai/agent-swarm/blob/main/skills/agent-swarm/references/upgrade.md
12
+
13
+ services:
14
+ swarm-api:
15
+ image: "ghcr.io/desplega-ai/agent-swarm:${AGENT_SWARM_VERSION:-latest}"
16
+ container_name: swarm-api
17
+ pull_policy: always
18
+ stop_grace_period: 60s
19
+
20
+ environment:
21
+ - API_KEY=${API_KEY}
22
+ - INSTALL_METHOD=${INSTALL_METHOD}
23
+ - INSTALL_PRESET=${INSTALL_PRESET:-}
24
+ - MEMORY_HYBRID_SEARCH=${MEMORY_HYBRID_SEARCH-1}
25
+ - MEMORY_GRAPH_EXPANSION=${MEMORY_GRAPH_EXPANSION-1}
26
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
27
+ - MEMORY_DEMOTION_FLOOR=${MEMORY_DEMOTION_FLOOR-1.0}
28
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
29
+ - MCP_BASE_URL=http://localhost:3013
30
+ - APP_URL=https://app.agent-swarm.dev
31
+
32
+ ports:
33
+ - "3013:3013"
34
+
35
+ volumes:
36
+ - swarm_data:/app/data
37
+
38
+ healthcheck:
39
+ test: ["CMD-SHELL", "curl -f http://localhost:3013/health || exit 1"]
40
+ interval: 10s
41
+ timeout: 5s
42
+ retries: 3
43
+ start_period: 15s
44
+
45
+ restart: unless-stopped
46
+
47
+ lead:
48
+ image: "ghcr.io/desplega-ai/agent-swarm-worker:${AGENT_SWARM_VERSION:-latest}"
49
+ container_name: swarm-lead
50
+ pull_policy: always
51
+ stop_grace_period: 60s
52
+
53
+ depends_on:
54
+ swarm-api:
55
+ condition: service_healthy
56
+
57
+ environment:
58
+ - HARNESS_PROVIDER=${HARNESS_PROVIDER}
59
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
60
+ - API_KEY=${API_KEY}
61
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
62
+ - AGENT_ID=00000000-0000-4000-8000-000000000001
63
+ - AGENT_NAME=Lead
64
+ - AGENT_ROLE=lead
65
+ - TEMPLATE_ID=official/lead
66
+ - MCP_BASE_URL=http://swarm-api:3013
67
+ - YOLO=true
68
+ - SWARM_URL=http://swarm-api:3013
69
+ - MAX_CONCURRENT_TASKS=2
70
+
71
+ ports:
72
+ - "3201:3000"
73
+
74
+ volumes:
75
+ - swarm_logs:/logs
76
+ - swarm_shared:/workspace/shared
77
+ - swarm_lead:/workspace/personal
78
+
79
+ restart: unless-stopped
80
+
81
+ worker-coder-1:
82
+ image: "ghcr.io/desplega-ai/agent-swarm-worker:${AGENT_SWARM_VERSION:-latest}"
83
+ container_name: swarm-worker-coder-1
84
+ pull_policy: always
85
+ stop_grace_period: 60s
86
+
87
+ depends_on:
88
+ swarm-api:
89
+ condition: service_healthy
90
+
91
+ environment:
92
+ - HARNESS_PROVIDER=${HARNESS_PROVIDER}
93
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
94
+ - API_KEY=${API_KEY}
95
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
96
+ - AGENT_ID=00000000-0000-4000-8000-000000000002
97
+ - AGENT_NAME=Coder 1
98
+ - AGENT_ROLE=worker
99
+ - TEMPLATE_ID=official/coder
100
+ - MCP_BASE_URL=http://swarm-api:3013
101
+ - YOLO=true
102
+ - SWARM_URL=http://swarm-api:3013
103
+ - MAX_CONCURRENT_TASKS=1
104
+
105
+ ports:
106
+ - "3202:3000"
107
+
108
+ volumes:
109
+ - swarm_logs:/logs
110
+ - swarm_shared:/workspace/shared
111
+ - swarm_worker_coder_1:/workspace/personal
112
+
113
+ restart: unless-stopped
114
+
115
+ worker-coder-2:
116
+ image: "ghcr.io/desplega-ai/agent-swarm-worker:${AGENT_SWARM_VERSION:-latest}"
117
+ container_name: swarm-worker-coder-2
118
+ pull_policy: always
119
+ stop_grace_period: 60s
120
+
121
+ depends_on:
122
+ swarm-api:
123
+ condition: service_healthy
124
+
125
+ environment:
126
+ - HARNESS_PROVIDER=${HARNESS_PROVIDER}
127
+ - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN}
128
+ - API_KEY=${API_KEY}
129
+ - MEMORY_RATERS=${MEMORY_RATERS-implicit-citation,explicit-self}
130
+ - AGENT_ID=00000000-0000-4000-8000-000000000003
131
+ - AGENT_NAME=Coder 2
132
+ - AGENT_ROLE=worker
133
+ - TEMPLATE_ID=official/coder
134
+ - MCP_BASE_URL=http://swarm-api:3013
135
+ - YOLO=true
136
+ - SWARM_URL=http://swarm-api:3013
137
+ - MAX_CONCURRENT_TASKS=1
138
+
139
+ ports:
140
+ - "3203:3000"
141
+
142
+ volumes:
143
+ - swarm_logs:/logs
144
+ - swarm_shared:/workspace/shared
145
+ - swarm_worker_coder_2:/workspace/personal
146
+
147
+ restart: unless-stopped
148
+
149
+ volumes:
150
+ swarm_data:
151
+ swarm_logs:
152
+ swarm_shared:
153
+ swarm_lead:
154
+ swarm_worker_coder_1:
155
+ swarm_worker_coder_2: