@desplega.ai/agent-swarm 1.149.1 → 1.151.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 (538) hide show
  1. package/README.md +18 -3
  2. package/dist/{acp-adapter-vhkzfpjg.js → acp-adapter-ex8hzjfc.js} +5 -5
  3. package/dist/{actions-9d2694yk.js → actions-2bgpyhww.js} +39 -11
  4. package/dist/{app-fq2ggynt.js → app-1706zhr1.js} +7 -7
  5. package/dist/{artifact-gj9arwrr.js → artifact-td4q4dch.js} +1 -1
  6. package/dist/{assistant-edb6n9nn.js → assistant-bavke5p7.js} +44 -20
  7. package/dist/{azure-openai-responses-cqar64rc.js → azure-openai-responses-f38x2avq.js} +13 -13
  8. package/dist/{boot-reembed-msweabbp.js → boot-reembed-3cmrrmpa.js} +9 -9
  9. package/dist/{boot-reembed-q5wd3tha.js → boot-reembed-nafcmmmc.js} +14 -16
  10. package/dist/{boot-scrub-logs-3g1az933.js → boot-scrub-logs-cd6a2sq0.js} +5 -5
  11. package/dist/{claude-adapter-v3rnzsdc.js → claude-adapter-wfp2gzvz.js} +15 -16
  12. package/dist/{claude-managed-adapter-qvsmh6mv.js → claude-managed-adapter-dsmkcrjy.js} +3 -3
  13. package/dist/{claude-sdk-session-qxrpsna1.js → claude-sdk-session-bht9jjak.js} +15 -16
  14. package/dist/{cli-5m0qmvdp.js → cli-0qb1z6s2.js} +1 -1
  15. package/dist/{cli-9d8ntetj.js → cli-2658f6at.js} +1 -1
  16. package/dist/{cli-7evafqvy.js → cli-2tbvf1z1.js} +85 -69
  17. package/dist/{cli-k351hv5k.js → cli-3v9xhjcn.js} +24 -12
  18. package/dist/{cli-1ebpar1q.js → cli-4wppfkcm.js} +350 -20
  19. package/dist/{cli-4260r1tg.js → cli-5jd2z7av.js} +97 -84
  20. package/dist/{cli-cv7s5zdq.js → cli-5tpgq60f.js} +9865 -715
  21. package/dist/{cli-6skz3rk8.js → cli-7tgcstn2.js} +9 -4
  22. package/dist/{cli-01g3x1ca.js → cli-9004vfdf.js} +108 -56
  23. package/dist/{cli-1c94wvcw.js → cli-a1z3h107.js} +124 -99
  24. package/dist/{cli-9br8ypfv.js → cli-czjtgfys.js} +2 -2
  25. package/dist/{cli-5my3bjsd.js → cli-d3p82erb.js} +7 -7
  26. package/dist/{cli-e29gmdmw.js → cli-dv6cdjs2.js} +2 -1
  27. package/dist/{cli-wby1xnnb.js → cli-f1wky6zp.js} +1 -1
  28. package/dist/{cli-zvz62chv.js → cli-fm4ytsdk.js} +4 -4
  29. package/dist/{cli-tg8qj8ee.js → cli-frcta2w4.js} +6 -6
  30. package/dist/{cli-7xx10h0a.js → cli-g69fdc9g.js} +2 -2
  31. package/dist/{cli-cmp8g3sw.js → cli-gbfwcd3k.js} +44 -9
  32. package/dist/{handlers-nsg0bcye.js → cli-gjyvhmmh.js} +97 -45
  33. package/dist/{cli-08b07b4r.js → cli-ht5rs63n.js} +1 -1
  34. package/dist/{cli-jecc01cb.js → cli-j4nv2wqy.js} +2 -4
  35. package/dist/{cli-cd60fv6j.js → cli-j9xczhaq.js} +1 -1
  36. package/dist/cli-pf9q3696.js +172 -0
  37. package/dist/{cli-xm87hzbw.js → cli-pgj4a5fb.js} +1 -1
  38. package/dist/{cli-jezx9b9c.js → cli-ppm4975n.js} +9 -3
  39. package/dist/{cli-3z634pqe.js → cli-q88st9aj.js} +2 -2
  40. package/dist/{cli-3sysyjve.js → cli-r2q6pevn.js} +142 -49
  41. package/dist/{cli-07jd68a1.js → cli-re8z5p8p.js} +1 -1
  42. package/dist/{cli-qgd4sqz5.js → cli-s14agm5s.js} +121 -14
  43. package/dist/{cli-svbrpf5q.js → cli-sjaae6ff.js} +9872 -424
  44. package/dist/{cli-73gq0zxn.js → cli-vwm416m6.js} +13 -13
  45. package/dist/{cli-4wtq5jjv.js → cli-wbyk465z.js} +1 -1
  46. package/dist/{cli-3apbzgyk.js → cli-z61ykvam.js} +19 -14
  47. package/dist/{cli-e06a8a7y.js → cli-zkxymas5.js} +4 -3
  48. package/dist/cli.js +26 -25
  49. package/dist/{codex-adapter-jyw7a91z.js → codex-adapter-jjjk8w4m.js} +8 -9
  50. package/dist/{codex-hook-hfrt9shr.js → codex-hook-8jexc34x.js} +3 -3
  51. package/dist/{codex-session-runner-bmngj0s5.js → codex-session-runner-nd6ayxkx.js} +8 -9
  52. package/dist/{commands-n755g391.js → commands-9v4psyq1.js} +5 -5
  53. package/dist/{db-s1cgh5gv.js → db-wnt58tpe.js} +5 -5
  54. package/dist/dispatcher-05jh1aqk.js +74 -0
  55. package/dist/{e2b-p04vmtx0.js → e2b-413b8t4v.js} +1 -1
  56. package/dist/{google-generative-ai-tsskx7te.js → google-generative-ai-ndjmj5fa.js} +7 -7
  57. package/dist/{google-vertex-ppw8ydpa.js → google-vertex-fr665tqs.js} +10 -10
  58. package/dist/handlers-tw90pkh5.js +65 -0
  59. package/dist/{hook-jf0xe8zh.js → hook-123e2scb.js} +11 -12
  60. package/dist/{hook-h9cqrm8q.js → hook-sxe3r349.js} +11 -12
  61. package/dist/{http-nc6pydw5.js → http-ecsar8ez.js} +1442 -581
  62. package/dist/{index-ezxkds2n.js → index-16js521z.js} +335 -107
  63. package/dist/{index-769nc012.js → index-hw26vj40.js} +25 -19
  64. package/dist/{index-0wdy6gwc.js → index-nnrbpcjp.js} +25 -17
  65. package/dist/index-ymn7em0p.js +25 -0
  66. package/dist/{index-x1zcj09z.js → index-zj518gf9.js} +26 -20
  67. package/dist/{keepalive-nesm3xb6.js → keepalive-asqtcm4y.js} +7 -7
  68. package/dist/{lead-bwy6t2za.js → lead-xbfr7fvt.js} +40 -48
  69. package/dist/{maintenance-8w393zf0.js → maintenance-qma55qvw.js} +9 -9
  70. package/dist/{oauth-refresh-sweep-sh8xjy08.js → oauth-refresh-sweep-3s04c6qw.js} +6 -6
  71. package/dist/{onboard-25ps29h1.js → onboard-drskd386.js} +13 -4
  72. package/dist/{openai-codex-responses-g7w48y30.js → openai-codex-responses-wy6a43wd.js} +13 -13
  73. package/dist/{openai-responses-nmeyptke.js → openai-responses-6xwf7bzg.js} +19 -19
  74. package/dist/{opencode-adapter-dce4wskd.js → opencode-adapter-28axqa09.js} +4 -4
  75. package/dist/{otel-impl-b93gxnz5.js → otel-impl-943c96er.js} +1 -1
  76. package/dist/{pi-mono-adapter-zvshk5cj.js → pi-mono-adapter-jcqt71cg.js} +17 -19
  77. package/dist/{pricing-refresh-5v56x7gb.js → pricing-refresh-mx51az05.js} +7 -7
  78. package/dist/{rbac-roles-x55cnezn.js → rbac-roles-78baecqd.js} +13 -9
  79. package/dist/{rbac-roles-0p0s6pbj.js → rbac-roles-wcmrg6sv.js} +7 -7
  80. package/dist/{render-v2-hyd45w8b.js → render-v2-8zjntgf5.js} +7 -7
  81. package/dist/{seed-pricing-49gbgn96.js → seed-pricing-jqjs6cws.js} +6 -6
  82. package/dist/{setup-qvq64vzq.js → setup-4pks0vfk.js} +2 -2
  83. package/dist/work-objects-wangt792.js +165 -0
  84. package/dist/{worker-scj60cxg.js → worker-p2mr422x.js} +40 -48
  85. package/openapi.json +1365 -268
  86. package/package.json +4 -3
  87. package/src/agentmail/handlers.ts +95 -66
  88. package/src/be/budget-refusal-notify.ts +1 -0
  89. package/src/be/db/tasks/read.ts +3 -0
  90. package/src/be/db/tasks/write.ts +13 -1
  91. package/src/be/db-client.ts +5 -0
  92. package/src/be/db.ts +15 -5
  93. package/src/be/extensions/db.ts +461 -0
  94. package/src/be/extensions/validate.ts +107 -0
  95. package/src/be/memory/boot-reembed.ts +17 -12
  96. package/src/be/memory/index.ts +12 -0
  97. package/src/be/memory/providers/openai-embedding.ts +4 -0
  98. package/src/be/memory/types.ts +2 -0
  99. package/src/be/migrations/153_deferred_task_wait_members.sql +25 -0
  100. package/src/be/migrations/154_routing_source.sql +3 -0
  101. package/src/be/migrations/155_extensions.sql +66 -0
  102. package/src/be/migrations/156_inbox_item_state_read_at.sql +7 -0
  103. package/src/be/rbac-roles.ts +3 -2
  104. package/src/be/scripts/typecheck.ts +59 -41
  105. package/src/be/seed/schedules-seeder.ts +25 -2
  106. package/src/be/seed/workflows-seeder.ts +17 -0
  107. package/src/be/seed-scripts/catalog/delegate.ts +3 -1
  108. package/src/be/seed-skills/bundled-files.generated.json +1 -1
  109. package/src/be/seed-skills/index.ts +7 -0
  110. package/src/be/steering.ts +1 -0
  111. package/src/be/swarm-config-guard.ts +3 -1
  112. package/src/commands/credential-refresh.ts +70 -0
  113. package/src/commands/onboard/compose-generator.ts +14 -2
  114. package/src/commands/onboard/env-generator.ts +7 -0
  115. package/src/commands/provider-credentials.ts +2 -25
  116. package/src/commands/runner.ts +24 -57
  117. package/src/extensions/apply-task-create.ts +135 -0
  118. package/src/extensions/bundle-path.ts +10 -0
  119. package/src/extensions/contract-runtime.ts +7 -0
  120. package/src/extensions/contract-types.generated.ts +4 -0
  121. package/src/extensions/contract.ts +270 -0
  122. package/src/extensions/ctx.ts +186 -0
  123. package/src/extensions/dispatcher.ts +479 -0
  124. package/src/extensions/identity.ts +44 -0
  125. package/src/extensions/lifecycle.ts +281 -0
  126. package/src/extensions/loader.ts +207 -0
  127. package/src/extensions/post-bridge.ts +161 -0
  128. package/src/github/handlers.ts +185 -140
  129. package/src/gitlab/handlers.ts +97 -77
  130. package/src/heartbeat/heartbeat.ts +155 -83
  131. package/src/http/agents.ts +1 -1
  132. package/src/http/all-routes.ts +1 -0
  133. package/src/http/approval-requests.ts +1 -0
  134. package/src/http/apps.ts +14 -9
  135. package/src/http/config.ts +4 -1
  136. package/src/http/core.ts +38 -2
  137. package/src/http/extensions.ts +547 -0
  138. package/src/http/inbox-state.ts +2 -0
  139. package/src/http/index.ts +41 -3
  140. package/src/http/mcp-bridge.ts +96 -62
  141. package/src/http/mcp.ts +1 -1
  142. package/src/http/script-runs.ts +5 -0
  143. package/src/http/status.ts +6 -4
  144. package/src/http/tasks.ts +51 -30
  145. package/src/integrations/kapso/inbound.ts +15 -10
  146. package/src/jira/sync.ts +26 -16
  147. package/src/linear/sync.ts +26 -16
  148. package/src/prompts/session-templates.ts +18 -13
  149. package/src/providers/claude-adapter.ts +21 -8
  150. package/src/rbac/admission.ts +1 -1
  151. package/src/rbac/elevated-agents.ts +24 -0
  152. package/src/rbac/legacy-policy.ts +35 -6
  153. package/src/rbac/permissions.ts +8 -0
  154. package/src/scheduler/deferred-task-waits.ts +138 -27
  155. package/src/scheduler/schedule-task.ts +54 -24
  156. package/src/scheduler/scheduler.ts +108 -125
  157. package/src/scripts-runtime/executors/native.ts +5 -1
  158. package/src/scripts-runtime/executors/types.ts +5 -0
  159. package/src/scripts-runtime/import-allowlist.ts +79 -19
  160. package/src/scripts-runtime/sdk-allowlist.ts +4 -0
  161. package/src/scripts-runtime/swarm-config.ts +8 -0
  162. package/src/scripts-runtime/swarm-sdk.ts +3 -0
  163. package/src/scripts-runtime/types/stdlib.d.ts +16 -3
  164. package/src/scripts-runtime/types/swarm-extension.d.ts +562 -0
  165. package/src/scripts-runtime/types/swarm-sdk.d.ts +16 -3
  166. package/src/server.ts +6 -0
  167. package/src/slack/HEURISTICS.md +3 -1
  168. package/src/slack/actions.ts +21 -16
  169. package/src/slack/app.ts +2 -0
  170. package/src/slack/assistant.ts +4 -12
  171. package/src/slack/blocks.ts +1 -1
  172. package/src/slack/handlers.ts +107 -19
  173. package/src/slack/inbound-files.ts +9 -5
  174. package/src/slack/render-v2.ts +188 -38
  175. package/src/slack/router.ts +13 -3
  176. package/src/slack/steering.ts +3 -3
  177. package/src/slack/thread-buffer.ts +66 -23
  178. package/src/slack/work-objects.test.ts +252 -0
  179. package/src/slack/work-objects.ts +118 -0
  180. package/src/tasks/errors.ts +9 -0
  181. package/src/tasks/sibling-awareness.ts +35 -1
  182. package/src/tasks/worker-follow-up.ts +67 -11
  183. package/src/tests/acp-adapter.test.ts +10 -10
  184. package/src/tests/agent-fs-live-url.test.ts +40 -0
  185. package/src/tests/agent-fs-provision-seeder.test.ts +12 -12
  186. package/src/tests/api-key-tracking.test.ts +18 -18
  187. package/src/tests/api-key.test.ts +4 -2
  188. package/src/tests/apps-rbac.test.ts +1 -1
  189. package/src/tests/apps-spike5.test.ts +1 -1
  190. package/src/tests/apps-sync-engine.test.ts +8 -8
  191. package/src/tests/apps-user-config.test.ts +1 -1
  192. package/src/tests/artifact-sdk.test.ts +8 -8
  193. package/src/tests/asset-key-mcp.test.ts +2 -0
  194. package/src/tests/automation-preflight-alert.test.ts +1 -1
  195. package/src/tests/base-prompt.test.ts +7 -6
  196. package/src/tests/budget-user-scope.test.ts +1 -1
  197. package/src/tests/budgets-routes.test.ts +1 -1
  198. package/src/tests/claude-adapter-binary.test.ts +22 -40
  199. package/src/tests/claude-adapter-otel.test.ts +13 -7
  200. package/src/tests/claude-adapter.test.ts +8 -6
  201. package/src/tests/claude-hook-credentials.test.ts +3 -3
  202. package/src/tests/claude-managed-adapter.test.ts +4 -4
  203. package/src/tests/claude-managed-setup.test.ts +3 -3
  204. package/src/tests/claude-sdk-lifecycle.test.ts +1 -1
  205. package/src/tests/claude-sdk-transport.test.ts +6 -6
  206. package/src/tests/claude-stop-hook.test.ts +8 -8
  207. package/src/tests/claude-worker-parity.test.ts +3 -3
  208. package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +5 -5
  209. package/src/tests/codex-adapter.test.ts +7 -5
  210. package/src/tests/codex-app-server.test.ts +2 -2
  211. package/src/tests/codex-login.test.ts +15 -15
  212. package/src/tests/codex-oauth-credential-info.test.ts +4 -4
  213. package/src/tests/codex-oauth-keep-warm.test.ts +4 -4
  214. package/src/tests/codex-oauth-refresh-lock.test.ts +1 -1
  215. package/src/tests/codex-oauth-storage.test.ts +7 -7
  216. package/src/tests/codex-pool.test.ts +1 -1
  217. package/src/tests/codex-steering-hook.test.ts +1 -1
  218. package/src/tests/codex-swarm-events.test.ts +1 -1
  219. package/src/tests/config-api-only-keys.test.ts +1 -1
  220. package/src/tests/config-session-auth.test.ts +2 -2
  221. package/src/tests/connection-embedded-auth.test.ts +20 -18
  222. package/src/tests/core-auth.test.ts +1 -1
  223. package/src/tests/create-page-tool.test.ts +3 -3
  224. package/src/tests/credential-refresh.test.ts +115 -0
  225. package/src/tests/credential-wait.test.ts +2 -2
  226. package/src/tests/credentials.test.ts +6 -4
  227. package/src/tests/db-queries-oauth.test.ts +40 -40
  228. package/src/tests/defer-task.test.ts +73 -8
  229. package/src/tests/deferred-task-wait-migration.test.ts +64 -0
  230. package/src/tests/deferred-task-wake.test.ts +349 -8
  231. package/src/tests/devin-adapter.test.ts +1 -1
  232. package/src/tests/devin-api.test.ts +1 -1
  233. package/src/tests/docs-index-footprint.test.js +3 -3
  234. package/src/tests/e2b-dispatch.test.ts +21 -19
  235. package/src/tests/e2e-claude-transport.test.ts +3 -3
  236. package/src/tests/e2e-redact.test.ts +6 -6
  237. package/src/tests/ensure-token.test.ts +68 -68
  238. package/src/tests/entrypoint-api-readiness.test.ts +1 -1
  239. package/src/tests/entrypoint-codex-oauth-seed.test.ts +13 -13
  240. package/src/tests/env-flag.test.ts +1 -0
  241. package/src/tests/events-http.test.ts +1 -1
  242. package/src/tests/extensions-db.test.ts +216 -0
  243. package/src/tests/extensions-dispatcher.test.ts +275 -0
  244. package/src/tests/extensions-example-heartbeat-remediate.test.ts +69 -0
  245. package/src/tests/extensions-example-mcp-install.test.ts +63 -0
  246. package/src/tests/extensions-example-no-exclamation-marks.test.ts +72 -0
  247. package/src/tests/extensions-example-rewrite-and-suppress.test.ts +70 -0
  248. package/src/tests/extensions-example-route-slack-channel.test.ts +217 -0
  249. package/src/tests/extensions-heartbeat.test.ts +291 -0
  250. package/src/tests/extensions-http.test.ts +431 -0
  251. package/src/tests/extensions-lead-equivalence.test.ts +49 -0
  252. package/src/tests/extensions-lifecycle.test.ts +209 -0
  253. package/src/tests/extensions-loader.test.ts +95 -0
  254. package/src/tests/extensions-mcp-tools.test.ts +245 -0
  255. package/src/tests/extensions-pre-task.test.ts +487 -0
  256. package/src/tests/extensions-run-context.test.ts +41 -0
  257. package/src/tests/extensions-tool-call.test.ts +288 -0
  258. package/src/tests/extensions-validate.test.ts +196 -0
  259. package/src/tests/fixtures/extensions/bad-import/hooks.ts +8 -0
  260. package/src/tests/fixtures/extensions/bad-import/manifest.json +9 -0
  261. package/src/tests/fixtures/extensions/bad-return-shape/hooks.ts +10 -0
  262. package/src/tests/fixtures/extensions/bad-return-shape/manifest.json +9 -0
  263. package/src/tests/fixtures/extensions/block-tasks-from-source/hooks.ts +22 -0
  264. package/src/tests/fixtures/extensions/block-tasks-from-source/manifest.json +9 -0
  265. package/src/tests/fixtures/extensions/ignore-channel/hooks.ts +22 -0
  266. package/src/tests/fixtures/extensions/ignore-channel/manifest.json +9 -0
  267. package/src/tests/fixtures/extensions/load.ts +10 -0
  268. package/src/tests/fixtures/extensions/minimal/hooks.ts +7 -0
  269. package/src/tests/fixtures/extensions/minimal/manifest.json +9 -0
  270. package/src/tests/fixtures/extensions/never-fail-long-tasks/hooks.ts +11 -0
  271. package/src/tests/fixtures/extensions/never-fail-long-tasks/manifest.json +9 -0
  272. package/src/tests/fixtures/extensions/no-exclamation-marks/hooks.ts +23 -0
  273. package/src/tests/fixtures/extensions/no-exclamation-marks/manifest.json +9 -0
  274. package/src/tests/fixtures/extensions/post-logger/hooks.ts +9 -0
  275. package/src/tests/fixtures/extensions/post-logger/manifest.json +9 -0
  276. package/src/tests/fixtures/extensions/priority-a/hooks.ts +7 -0
  277. package/src/tests/fixtures/extensions/priority-a/manifest.json +9 -0
  278. package/src/tests/fixtures/extensions/priority-b/hooks.ts +7 -0
  279. package/src/tests/fixtures/extensions/priority-b/manifest.json +9 -0
  280. package/src/tests/fixtures/extensions/record-only-on-tag/hooks.ts +16 -0
  281. package/src/tests/fixtures/extensions/record-only-on-tag/manifest.json +9 -0
  282. package/src/tests/fixtures/extensions/reserved-assets/hooks.ts +5 -0
  283. package/src/tests/fixtures/extensions/reserved-assets/manifest.json +10 -0
  284. package/src/tests/fixtures/extensions/rewrite-progress-prefix/hooks.ts +22 -0
  285. package/src/tests/fixtures/extensions/rewrite-progress-prefix/manifest.json +9 -0
  286. package/src/tests/fixtures/extensions/rewrite-task-priority/hooks.ts +7 -0
  287. package/src/tests/fixtures/extensions/rewrite-task-priority/manifest.json +9 -0
  288. package/src/tests/fixtures/extensions/route-channel-to-agent/hooks.ts +26 -0
  289. package/src/tests/fixtures/extensions/route-channel-to-agent/manifest.json +9 -0
  290. package/src/tests/fixtures/extensions/slow/hooks.ts +10 -0
  291. package/src/tests/fixtures/extensions/slow/manifest.json +9 -0
  292. package/src/tests/fixtures/extensions/suppress-lead-follow-up/hooks.ts +12 -0
  293. package/src/tests/fixtures/extensions/suppress-lead-follow-up/manifest.json +9 -0
  294. package/src/tests/fixtures/extensions/throws/hooks.ts +12 -0
  295. package/src/tests/fixtures/extensions/throws/manifest.json +9 -0
  296. package/src/tests/fixtures/extensions/worker-runtime/hooks.ts +5 -0
  297. package/src/tests/fixtures/extensions/worker-runtime/manifest.json +9 -0
  298. package/src/tests/fs-routes.test.ts +1 -1
  299. package/src/tests/gitlab-auth.test.ts +10 -10
  300. package/src/tests/harness-provider-resolution.test.ts +8 -5
  301. package/src/tests/heartbeat-reroute-decision.test.ts +1 -0
  302. package/src/tests/helper-credentials.test.ts +137 -0
  303. package/src/tests/http/context-routes.test.ts +2 -2
  304. package/src/tests/http-api-integration.test.ts +5 -2
  305. package/src/tests/http-users.test.ts +1 -1
  306. package/src/tests/identity-refresh.test.ts +2 -2
  307. package/src/tests/internal-ai/complete-structured.test.ts +2 -2
  308. package/src/tests/internal-ai/credentials.test.ts +19 -17
  309. package/src/tests/jira-metadata.test.ts +1 -1
  310. package/src/tests/jira-oauth.test.ts +5 -5
  311. package/src/tests/jira-sync.test.ts +1 -1
  312. package/src/tests/jira-webhook-lifecycle.test.ts +3 -3
  313. package/src/tests/jira-webhook.test.ts +2 -2
  314. package/src/tests/kapso-inbound.test.ts +2 -2
  315. package/src/tests/kv-http.test.ts +1 -1
  316. package/src/tests/kv-namespace-resolution.test.ts +1 -1
  317. package/src/tests/kv-page-proxy.test.ts +2 -2
  318. package/src/tests/launch-password-rejection.test.ts +2 -2
  319. package/src/tests/linear-webhook.test.ts +1 -1
  320. package/src/tests/mcp-oauth-dcr-reuse.test.ts +6 -6
  321. package/src/tests/mcp-oauth-ensure-token.test.ts +28 -22
  322. package/src/tests/mcp-oauth-manual-client.test.ts +16 -12
  323. package/src/tests/mcp-oauth-queries.test.ts +35 -32
  324. package/src/tests/mcp-oauth-resolve-secrets.test.ts +8 -8
  325. package/src/tests/mcp-oauth-wrapper.test.ts +20 -20
  326. package/src/tests/mcp-user-route.test.ts +1 -1
  327. package/src/tests/memory-edges.test.ts +1 -1
  328. package/src/tests/memory-edit-authorization.test.ts +32 -0
  329. package/src/tests/memory-rate-endpoint.test.ts +1 -1
  330. package/src/tests/memory-rate-tool.test.ts +2 -2
  331. package/src/tests/memory-rater-e2e.test.ts +1 -1
  332. package/src/tests/memory-rater-llm-summarizer.test.ts +3 -3
  333. package/src/tests/memory-rater-llm.test.ts +1 -1
  334. package/src/tests/model-control.test.ts +3 -0
  335. package/src/tests/multi-runtime-enabled-stats.test.ts +2 -2
  336. package/src/tests/multi-runtime-registration.test.ts +111 -17
  337. package/src/tests/oauth-access-token-tool.test.ts +18 -18
  338. package/src/tests/oauth-callback-flow.test.ts +8 -8
  339. package/src/tests/oauth-credential-bindings.test.ts +29 -27
  340. package/src/tests/oauth-keepalive.test.ts +10 -10
  341. package/src/tests/oauth-presets.test.ts +13 -5
  342. package/src/tests/oauth-refresh-failure.test.ts +9 -9
  343. package/src/tests/oauth-refresh-sweep.test.ts +20 -13
  344. package/src/tests/oauth-wrapper.test.ts +1 -1
  345. package/src/tests/onboard-compose.test.ts +47 -3
  346. package/src/tests/onboard-env.test.ts +26 -26
  347. package/src/tests/onboard-non-interactive.test.ts +4 -4
  348. package/src/tests/opencode-adapter.test.ts +1 -1
  349. package/src/tests/opencode-plugin.test.ts +2 -2
  350. package/src/tests/otel-session-cost-metrics.test.ts +1 -1
  351. package/src/tests/page-proxy-authed.test.ts +2 -2
  352. package/src/tests/page-proxy.test.ts +2 -2
  353. package/src/tests/page-session.test.ts +7 -7
  354. package/src/tests/page-viewer-auth.test.ts +2 -2
  355. package/src/tests/pages-authed-mode.test.ts +1 -1
  356. package/src/tests/pages-http.test.ts +1 -1
  357. package/src/tests/pages-password-mode.test.ts +1 -1
  358. package/src/tests/pages-public-authed-401.test.ts +1 -1
  359. package/src/tests/pages-public-html.test.ts +2 -2
  360. package/src/tests/pages-view-count.test.ts +1 -1
  361. package/src/tests/pi-mono-adapter.test.ts +10 -10
  362. package/src/tests/pi-mono-extension.test.ts +2 -2
  363. package/src/tests/preload.ts +5 -0
  364. package/src/tests/pricing-routes.test.ts +1 -1
  365. package/src/tests/profile-sync-warning.test.ts +8 -8
  366. package/src/tests/profile-sync.test.ts +8 -8
  367. package/src/tests/prompt-template-session.test.ts +36 -5
  368. package/src/tests/provider-process-group.test.ts +95 -4
  369. package/src/tests/providers/pi-cost.test.ts +1 -1
  370. package/src/tests/queue-stall-alarm.test.ts +1 -1
  371. package/src/tests/rbac-admission.test.ts +19 -4
  372. package/src/tests/rbac-charact-http.test.ts +1 -1
  373. package/src/tests/rbac-e2e-helpers.ts +1 -1
  374. package/src/tests/rbac-engine.test.ts +39 -0
  375. package/src/tests/realtime-room-auth.test.ts +1 -1
  376. package/src/tests/realtime-room-surfaces.test.ts +1 -1
  377. package/src/tests/reload-config.test.ts +45 -1
  378. package/src/tests/routing-affinity-inventory.test.ts +1 -1
  379. package/src/tests/routing-reason-contract.test.ts +76 -3
  380. package/src/tests/routing-reason-inventory.test.ts +11 -6
  381. package/src/tests/routing-source.test.ts +53 -0
  382. package/src/tests/runner-agent-fs-provision-retry.test.ts +1 -1
  383. package/src/tests/runner-context-preamble.test.ts +1 -1
  384. package/src/tests/runner-deployment-resume.test.ts +1 -1
  385. package/src/tests/runner-fallback-output.test.ts +1 -1
  386. package/src/tests/runner-identity-refresh.test.ts +1 -1
  387. package/src/tests/runner-skills-refresh.test.ts +1 -1
  388. package/src/tests/schedule-target-type.test.ts +3 -3
  389. package/src/tests/scheduled-tasks.test.ts +14 -5
  390. package/src/tests/scheduler-occurrence.test.ts +347 -0
  391. package/src/tests/script-apis-mcp.test.ts +1 -1
  392. package/src/tests/script-connections-http.test.ts +61 -58
  393. package/src/tests/script-connections-mcp.test.ts +1 -1
  394. package/src/tests/script-connections.test.ts +3 -1
  395. package/src/tests/script-runs-http.test.ts +15 -7
  396. package/src/tests/script-workflows-runtime-e2e.test.ts +1 -1
  397. package/src/tests/scripts-boot-reembed.test.ts +4 -0
  398. package/src/tests/scripts-embeddings.test.ts +4 -0
  399. package/src/tests/scripts-external-api.test.ts +1 -1
  400. package/src/tests/scripts-http.test.ts +1 -1
  401. package/src/tests/scripts-import-allowlist.test.ts +44 -1
  402. package/src/tests/scripts-mcp-e2e.test.ts +81 -1
  403. package/src/tests/scripts-only-gating.test.ts +4 -2
  404. package/src/tests/scripts-retention.test.ts +1 -1
  405. package/src/tests/scripts-runtime-identity.test.ts +2 -2
  406. package/src/tests/scripts-runtime-secret-egress.test.ts +1 -1
  407. package/src/tests/scripts-runtime.test.ts +6 -4
  408. package/src/tests/scripts-typecheck.test.ts +21 -0
  409. package/src/tests/sdk-allowlist.test.ts +1 -1
  410. package/src/tests/secret-scrubber.test.ts +38 -31
  411. package/src/tests/seed-registry.test.ts +46 -8
  412. package/src/tests/seed-schedules.test.ts +44 -9
  413. package/src/tests/seed-workflows.test.ts +21 -9
  414. package/src/tests/send-task-output-schema.test.ts +9 -1
  415. package/src/tests/send-task-requested-by.test.ts +1 -0
  416. package/src/tests/send-task-slack-routing-guard.test.ts +2 -0
  417. package/src/tests/session-costs-codex-recompute.test.ts +1 -1
  418. package/src/tests/session-costs-golden.test.ts +2 -2
  419. package/src/tests/session-costs-model-key-normalize.test.ts +2 -2
  420. package/src/tests/session-costs-recompute-all-providers.test.ts +1 -1
  421. package/src/tests/session-tokens.test.ts +1 -1
  422. package/src/tests/shutdown-error-scrubbing.test.ts +1 -1
  423. package/src/tests/slack-blocks.test.ts +12 -1
  424. package/src/tests/slack-file-tools-attachments.test.ts +1 -1
  425. package/src/tests/slack-inbound-files.test.ts +222 -86
  426. package/src/tests/slack-reaction-config.test.ts +5 -4
  427. package/src/tests/slack-read-boundaries.test.ts +1 -1
  428. package/src/tests/slack-render-v2.test.ts +196 -4
  429. package/src/tests/slack-router.test.ts +17 -2
  430. package/src/tests/slack-steering.test.ts +19 -0
  431. package/src/tests/status.test.ts +19 -7
  432. package/src/tests/steering-core.test.ts +1 -1
  433. package/src/tests/steering-enabled.test.ts +6 -8
  434. package/src/tests/steering-transport.test.ts +4 -4
  435. package/src/tests/store-progress-output-guidance.test.ts +34 -0
  436. package/src/tests/swarm-tool-result-gate.test.ts +11 -11
  437. package/src/tests/swarm-x-tool.test.ts +7 -5
  438. package/src/tests/sync-ai-toolbox-skills.test.ts +19 -0
  439. package/src/tests/task-supersede-resume.test.ts +1 -1
  440. package/src/tests/task-tool-preload-mcp.test.ts +4 -1
  441. package/src/tests/task-tools-ctx.test.ts +2 -0
  442. package/src/tests/tasks-requested-by-filter.test.ts +2 -2
  443. package/src/tests/telemetry-init.test.ts +11 -3
  444. package/src/tests/tool-annotations.test.ts +1 -1
  445. package/src/tests/tool-output-agent-id.test.ts +1 -0
  446. package/src/tests/tool-registrar-no-input.test.ts +42 -1
  447. package/src/tests/tracker-fold.test.ts +7 -7
  448. package/src/tests/tracker-tools.test.ts +3 -3
  449. package/src/tests/ui-followup-lead-delegation.test.ts +1 -0
  450. package/src/tests/unified-oauth-migration.test.ts +5 -5
  451. package/src/tests/user-token-rest-auth.test.ts +1 -1
  452. package/src/tests/user-token-routes.test.ts +1 -1
  453. package/src/tests/whoami-route.test.ts +1 -1
  454. package/src/tests/workflow-agent-task.test.ts +15 -13
  455. package/src/tests/workflow-ctx.test.ts +1 -1
  456. package/src/tests/workflow-e2e.test.ts +1 -1
  457. package/src/tests/workflow-engine-v2.test.ts +3 -1
  458. package/src/tests/workflow-executors.test.ts +2 -2
  459. package/src/tests/workflow-http-v2.test.ts +8 -6
  460. package/src/tests/workflow-input-redaction.test.ts +7 -5
  461. package/src/tests/workflow-integration-io.test.ts +2 -2
  462. package/src/tests/workflow-llm.test.ts +5 -5
  463. package/src/tests/workflow-registry.test.ts +1 -1
  464. package/src/tests/workflow-swarm-script.test.ts +1 -1
  465. package/src/tests/workflow-triggers-v2.test.ts +23 -21
  466. package/src/tests/x-composio.test.ts +9 -7
  467. package/src/tests/x402-client.test.ts +1 -1
  468. package/src/tests/x402-config.test.ts +28 -41
  469. package/src/tools/defer-task.ts +156 -24
  470. package/src/tools/extension-common.ts +84 -0
  471. package/src/tools/extension-install.ts +65 -0
  472. package/src/tools/extension-list.ts +66 -0
  473. package/src/tools/script-common.ts +43 -18
  474. package/src/tools/send-task.ts +87 -105
  475. package/src/tools/skills/skill-publish.ts +1 -0
  476. package/src/tools/store-progress.ts +1 -1
  477. package/src/tools/task-action.ts +43 -22
  478. package/src/tools/task-tool-ctx.ts +2 -0
  479. package/src/tools/templates.ts +2 -1
  480. package/src/tools/tool-config.ts +3 -1
  481. package/src/tools/utils.ts +140 -16
  482. package/src/types.ts +144 -0
  483. package/src/utils/constants.ts +7 -1
  484. package/src/utils/credentials.test.ts +16 -16
  485. package/src/utils/multi-runtime.ts +2 -2
  486. package/src/utils/steering-enabled.ts +4 -4
  487. package/src/workflows/executors/agent-task.ts +18 -3
  488. package/templates/ai-toolbox.manifest.json +7 -1
  489. package/templates/extensions/README.md +17 -0
  490. package/templates/extensions/notify-on-complete/README.md +11 -0
  491. package/templates/extensions/notify-on-complete/hooks.ts +61 -0
  492. package/templates/extensions/notify-on-complete/manifest.json +7 -0
  493. package/templates/extensions/require-ticket-ref/README.md +11 -0
  494. package/templates/extensions/require-ticket-ref/hooks.ts +30 -0
  495. package/templates/extensions/require-ticket-ref/manifest.json +7 -0
  496. package/templates/extensions/require-verification-note/README.md +11 -0
  497. package/templates/extensions/require-verification-note/hooks.ts +32 -0
  498. package/templates/extensions/require-verification-note/manifest.json +7 -0
  499. package/templates/schedules/daily-hn-briefing/config.json +1 -1
  500. package/templates/schedules/gtm-weekly-review/config.json +1 -1
  501. package/templates/schedules/weekly-code-health-reports/config.json +1 -1
  502. package/templates/schedules/weekly-dependabot-triage/config.json +1 -1
  503. package/templates/schedules/weekly-dora-metrics/config.json +1 -1
  504. package/templates/schedules/weekly-harness-upgrade-check/config.json +1 -1
  505. package/templates/skills/delegate-work/files/scripts/codex-exec.sh +1 -1
  506. package/templates/skills/scheduling/content.md +2 -0
  507. package/templates/skills/serply-search/SKILL.md +95 -0
  508. package/templates/skills/serply-search/config.json +13 -0
  509. package/templates/skills/serply-search/content.md +90 -0
  510. package/templates/skills/swarm-extensions/config.json +14 -0
  511. package/templates/skills/swarm-extensions/content.md +120 -0
  512. package/templates/skills/swarm-scripts/SKILL.md +2 -2
  513. package/templates/skills/swarm-scripts/content.md +2 -2
  514. package/templates/workflows/claude-code-changelog-watch/config.json +1 -1
  515. package/templates/workflows/gsc-topic-miner/config.json +1 -1
  516. package/templates/workflows/linear-drain-loop/config.json +1 -1
  517. package/templates/workflows/llm-safe-release-context/config.json +1 -1
  518. package/templates/workflows/ralph-loop/config.json +1 -1
  519. package/dist/cli-7fehefdf.js +0 -562
  520. package/dist/cli-ayvy5kde.js +0 -164
  521. package/dist/cli-ddfw1mc4.js +0 -4322
  522. package/dist/cli-hzqmgcm2.js +0 -3066
  523. package/dist/cli-j4d4f6hv.js +0 -338
  524. package/dist/cli-qgm2pfpq.js +0 -6377
  525. package/dist/cli-sdzq01t9.js +0 -823
  526. package/dist/cli-xvkmedgn.js +0 -332
  527. package/dist/cli-y3pq4v9g.js +0 -664
  528. package/dist/{anthropic-messages-vs2rabzp.js → anthropic-messages-2y8nktar.js} +19 -19
  529. package/dist/{claude-managed-setup-f5pmsyrp.js → claude-managed-setup-48dwg9bv.js} +3 -3
  530. package/dist/{cli-81r683bv.js → cli-ch38q5z4.js} +0 -0
  531. package/dist/{cli-6664w7y4.js → cli-kj76p1ez.js} +8 -8
  532. package/dist/{cli-c71mg51n.js → cli-r2fpe7cx.js} +5 -5
  533. package/dist/{cli-4xz3pmrq.js → cli-y6x0gqtg.js} +16 -16
  534. package/dist/{index-aa3sa6s8.js → index-2wsdsnmm.js} +1 -1
  535. package/dist/{mistral-conversations-4ryk7h83.js → mistral-conversations-qhr84ph3.js} +9 -9
  536. package/dist/{openai-completions-0bqmsajw.js → openai-completions-32rdwmze.js} +19 -19
  537. package/dist/{openrouter-images-qx18fyp8.js → openrouter-images-9f9ek4rw.js} +3 -3
  538. package/dist/{pi-messages-79jvzz1d.js → pi-messages-b1mbr6gp.js} +4 -4
@@ -26,7 +26,7 @@
26
26
  # Env overrides (flags -m/-e take precedence):
27
27
  # CODEX_MODEL default: gpt-5.6-sol gpt-5.6-sol | gpt-5.6-terra | gpt-5.6-luna
28
28
  # CODEX_EFFORT default: high reasoning effort (never "fast"/low)
29
- # CODEX_SANDBOX default: workspace-write read-only | workspace-write | danger-full-access
29
+ # CODEX_SANDBOX default: workspace-write (passed to codex's -s option)
30
30
  # CODEX_BYPASS set to 1 to use --dangerously-bypass-approvals-and-sandbox
31
31
  # (fully unsandboxed — opt in only when a phase must write
32
32
  # outside its worktree; overrides CODEX_SANDBOX)
@@ -45,6 +45,8 @@ Tasks created by a schedule are automatic tasks. Their completed output is not s
45
45
 
46
46
  A task whose answer needs time (a build, a deploy, a reply) calls `defer-task` with `delayMs` or `runAt`, a `summary` of what you did so far, and a `note` that says what is pending. The tool completes the task and creates the one-off schedule for you. The task reaches its final state (`completed`) on this call, and the `summary` becomes its output. The wake-up task carries the deferred task as its parent, so you receive that task's context. Add `checks` to list what to verify on wake-up. Do not hand-roll this with `create-schedule`.
47
47
 
48
+ When waiting on tasks, include `wakeOn:{event:"settled",taskIds:["<id>"],mode:"all"}` alongside `delayMs` or `runAt`. The displayed time is a ceiling; matching task outcomes wake you sooner.
49
+
48
50
  ## Secrets
49
51
 
50
52
  A `taskTemplate` and `scriptArgs` are stored as plain text and replayed on every run. They must not contain a token, password, or key. Call the external API from a script through a registered connection or a credential binding instead. See the `swarm-scripts` skill, section Secrets.
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: serply-search
3
+ description: Query real Google results through Serply, with separate endpoints for news (dated coverage) and scholar (citation counts). Use when the ranking itself, the publication date, or the citation count is the answer.
4
+ ---
5
+
6
+ # Serply Search
7
+
8
+ Serply (https://serply.io) is a Google SERP API. It returns the ranked organic results for a keyword query, and exposes Google News and Google Scholar as separate endpoints. API reference: https://serply.io/docs
9
+
10
+ ## When to use Serply vs. Exa vs. WebSearch
11
+
12
+ | Query shape | Use |
13
+ |---|---|
14
+ | "Companies building agent coordination layers" | Exa (conceptual, embedding match) |
15
+ | "Blogs that argue knowledge is not data" | Exa (argument-shape) |
16
+ | "What ranks on page 1 for `bun sqlite orm`" | **Serply** search (the ranking is the answer) |
17
+ | "Funding rounds for company X since June" | **Serply** news (named entity plus date) |
18
+ | "How heavily cited is paper Y" | **Serply** scholar (citation counts) |
19
+ | "What is the official Bun docs URL?" | WebSearch (one concrete lookup) |
20
+
21
+ Exa ranks by embedding similarity, so it wins at "find me things shaped like this". Serply returns what Google actually ranks, which is what you want when position, recency, or citation weight is the thing being measured. A plain WebSearch is still the cheapest way to settle a single fact.
22
+
23
+ ## Step 1. Get the API key
24
+
25
+ ```bash
26
+ # Via MCP tool (preferred, handles secret resolution)
27
+ mcp__agent-swarm__get-config(key="SERPLY_API_KEY", includeSecrets=true)
28
+ ```
29
+
30
+ The value comes back at `configs[0].value`. Export to env or pass inline. Keys come from https://serply.io
31
+
32
+ ## Step 2. Web search
33
+
34
+ ```bash
35
+ curl -sS 'https://api.serply.io/v1/search/?q=bun+sqlite+orm&num=10' \
36
+ -H "X-Api-Key: $SERPLY_API_KEY" \
37
+ -H 'User-Agent: agent-swarm/1.0'
38
+ ```
39
+
40
+ Parameters go in the query string:
41
+
42
+ - `q` (required): URL-encoded keywords, not a natural-language description. Google operators pass straight through, so `q=sqlite+site%3Abun.sh` and `tbs=` date filters behave as they do in the browser.
43
+ - `num`: how many results to return. Honored up to 10 and clamped there, so page instead of asking for 20.
44
+
45
+ Response (trimmed):
46
+
47
+ ```json
48
+ {
49
+ "results": [
50
+ {
51
+ "title": "Use Drizzle ORM with Bun | Bun Guides",
52
+ "description": "Drizzle is an ORM that supports both a SQL-like \"query builder\" API and an ORM-like Queries API.",
53
+ "position": 1,
54
+ "realPosition": 1,
55
+ "result_type": "organic",
56
+ "link": "https://bun.com/guides/ecosystem/drizzle"
57
+ }
58
+ ]
59
+ }
60
+ ```
61
+
62
+ The snippet field is `description`, not `snippet`, and the URL field is `link`, not `url`. Each row also carries `metadata.display_url`. The payload has `answers`, `knowledge_graph` and `related_questions` beside `results`, populated only when Google returned them and empty otherwise.
63
+
64
+ ## Step 3. News and scholar
65
+
66
+ Same host and header, different path, different response key.
67
+
68
+ ```bash
69
+ curl -sS 'https://api.serply.io/v1/news/?q=openai+funding' \
70
+ -H "X-Api-Key: $SERPLY_API_KEY" -H 'User-Agent: agent-swarm/1.0'
71
+ ```
72
+
73
+ News rows land in `entries[]`, each with `title`, `link`, `published` (RFC 1123), `summary`, and `source.title`. It returns the whole feed and ignores `num`.
74
+
75
+ ```bash
76
+ curl -sS 'https://api.serply.io/v1/scholar/?q=attention+is+all+you+need&num=3' \
77
+ -H "X-Api-Key: $SERPLY_API_KEY" -H 'User-Agent: agent-swarm/1.0'
78
+ ```
79
+
80
+ Scholar rows land in `articles[]`, each with `title`, `link`, `description`, `author.names`, and `extras.citations.count` as a string like `"Cited by 269516"`. When Google found a PDF, `doc.link` points at it.
81
+
82
+ ## Step 4. Pair with WebFetch
83
+
84
+ A SERP row gives you a title, a snippet, and a rank. For anything you will cite, fetch the page. Serply is the index, WebFetch is the source.
85
+
86
+ ## Discipline: no fabrication
87
+
88
+ If a query surfaces nothing relevant, write "not surfaced" rather than inventing a plausible link. A search that came back thin is a real finding and worth reporting as one.
89
+
90
+ ## Quick gotchas
91
+
92
+ - The header is `X-Api-Key` holding the bare key, **not** `Authorization: Bearer`.
93
+ - Serply sits behind Cloudflare, which rejects a default library User-Agent. Python `urllib` gets `HTTP 403` with the body `error code: 1010`. Send an explicit `User-Agent`; curl's own default is accepted.
94
+ - `/v1/scholar/` returns both `articles` and an empty `results: []`. Read `articles`. Reading `results` gives you zero papers for every query, and nothing about the response says why.
95
+ - Rankings are location-dependent, so two runs from different regions can legitimately disagree. Record the query alongside the positions whenever the position is the point.
@@ -0,0 +1,13 @@
1
+ {
2
+ "kind": "skill",
3
+ "name": "serply-search",
4
+ "displayName": "Serply Search",
5
+ "slug": "serply-search",
6
+ "title": "Serply Search",
7
+ "description": "Query real Google results through Serply, with separate endpoints for news (dated coverage) and scholar (citation counts). Use when the ranking itself, the publication date, or the citation count is the answer.",
8
+ "version": "1.0.0",
9
+ "category": "skills",
10
+ "placeholders": ["SERPLY_API_KEY"],
11
+ "runAllSeedersCandidate": false,
12
+ "tags": ["research", "search", "web"]
13
+ }
@@ -0,0 +1,90 @@
1
+ # Serply Search
2
+
3
+ Serply (https://serply.io) is a Google SERP API. It returns the ranked organic results for a keyword query, and exposes Google News and Google Scholar as separate endpoints. API reference: https://serply.io/docs
4
+
5
+ ## When to use Serply vs. Exa vs. WebSearch
6
+
7
+ | Query shape | Use |
8
+ |---|---|
9
+ | "Companies building agent coordination layers" | Exa (conceptual, embedding match) |
10
+ | "Blogs that argue knowledge is not data" | Exa (argument-shape) |
11
+ | "What ranks on page 1 for `bun sqlite orm`" | **Serply** search (the ranking is the answer) |
12
+ | "Funding rounds for company X since June" | **Serply** news (named entity plus date) |
13
+ | "How heavily cited is paper Y" | **Serply** scholar (citation counts) |
14
+ | "What is the official Bun docs URL?" | WebSearch (one concrete lookup) |
15
+
16
+ Exa ranks by embedding similarity, so it wins at "find me things shaped like this". Serply returns what Google actually ranks, which is what you want when position, recency, or citation weight is the thing being measured. A plain WebSearch is still the cheapest way to settle a single fact.
17
+
18
+ ## Step 1. Get the API key
19
+
20
+ ```bash
21
+ # Via MCP tool (preferred, handles secret resolution)
22
+ mcp__agent-swarm__get-config(key="SERPLY_API_KEY", includeSecrets=true)
23
+ ```
24
+
25
+ The value comes back at `configs[0].value`. Export to env or pass inline. Keys come from https://serply.io
26
+
27
+ ## Step 2. Web search
28
+
29
+ ```bash
30
+ curl -sS 'https://api.serply.io/v1/search/?q=bun+sqlite+orm&num=10' \
31
+ -H "X-Api-Key: $SERPLY_API_KEY" \
32
+ -H 'User-Agent: agent-swarm/1.0'
33
+ ```
34
+
35
+ Parameters go in the query string:
36
+
37
+ - `q` (required): URL-encoded keywords, not a natural-language description. Google operators pass straight through, so `q=sqlite+site%3Abun.sh` and `tbs=` date filters behave as they do in the browser.
38
+ - `num`: how many results to return. Honored up to 10 and clamped there, so page instead of asking for 20.
39
+
40
+ Response (trimmed):
41
+
42
+ ```json
43
+ {
44
+ "results": [
45
+ {
46
+ "title": "Use Drizzle ORM with Bun | Bun Guides",
47
+ "description": "Drizzle is an ORM that supports both a SQL-like \"query builder\" API and an ORM-like Queries API.",
48
+ "position": 1,
49
+ "realPosition": 1,
50
+ "result_type": "organic",
51
+ "link": "https://bun.com/guides/ecosystem/drizzle"
52
+ }
53
+ ]
54
+ }
55
+ ```
56
+
57
+ The snippet field is `description`, not `snippet`, and the URL field is `link`, not `url`. Each row also carries `metadata.display_url`. The payload has `answers`, `knowledge_graph` and `related_questions` beside `results`, populated only when Google returned them and empty otherwise.
58
+
59
+ ## Step 3. News and scholar
60
+
61
+ Same host and header, different path, different response key.
62
+
63
+ ```bash
64
+ curl -sS 'https://api.serply.io/v1/news/?q=openai+funding' \
65
+ -H "X-Api-Key: $SERPLY_API_KEY" -H 'User-Agent: agent-swarm/1.0'
66
+ ```
67
+
68
+ News rows land in `entries[]`, each with `title`, `link`, `published` (RFC 1123), `summary`, and `source.title`. It returns the whole feed and ignores `num`.
69
+
70
+ ```bash
71
+ curl -sS 'https://api.serply.io/v1/scholar/?q=attention+is+all+you+need&num=3' \
72
+ -H "X-Api-Key: $SERPLY_API_KEY" -H 'User-Agent: agent-swarm/1.0'
73
+ ```
74
+
75
+ Scholar rows land in `articles[]`, each with `title`, `link`, `description`, `author.names`, and `extras.citations.count` as a string like `"Cited by 269516"`. When Google found a PDF, `doc.link` points at it.
76
+
77
+ ## Step 4. Pair with WebFetch
78
+
79
+ A SERP row gives you a title, a snippet, and a rank. For anything you will cite, fetch the page. Serply is the index, WebFetch is the source.
80
+
81
+ ## Discipline: no fabrication
82
+
83
+ If a query surfaces nothing relevant, write "not surfaced" rather than inventing a plausible link. A search that came back thin is a real finding and worth reporting as one.
84
+
85
+ ## Quick gotchas
86
+
87
+ - The header is `X-Api-Key` holding the bare key, **not** `Authorization: Bearer`.
88
+ - Serply sits behind Cloudflare, which rejects a default library User-Agent. Python `urllib` gets `HTTP 403` with the body `error code: 1010`. Send an explicit `User-Agent`; curl's own default is accepted.
89
+ - `/v1/scholar/` returns both `articles` and an empty `results: []`. Read `articles`. Reading `results` gives you zero papers for every query, and nothing about the response says why.
90
+ - Rankings are location-dependent, so two runs from different regions can legitimately disagree. Record the query alongside the positions whenever the position is the point.
@@ -0,0 +1,14 @@
1
+ {
2
+ "kind": "skill",
3
+ "name": "swarm-extensions",
4
+ "displayName": "Swarm Extensions",
5
+ "slug": "swarm-extensions",
6
+ "title": "Swarm Extensions",
7
+ "description": "Write, install, and manage swarm extensions: TypeScript hook bundles that block, modify, or observe task creation, follow-ups, Slack routing, heartbeat remediation, and tool calls. Covers the hook contract, where to fetch swarm-extension.d.ts, the extension-install and extension-list tools, config schemas, and the operator enable step.",
8
+ "version": "1.0.0",
9
+ "category": "skills",
10
+ "placeholders": [],
11
+ "runAllSeedersCandidate": true,
12
+ "systemDefault": true,
13
+ "tags": ["extensions", "hooks", "policy", "automation"]
14
+ }
@@ -0,0 +1,120 @@
1
+ # Swarm Extensions
2
+
3
+ An extension is a trusted TypeScript hook bundle that runs inside the swarm API server. Use one when a rule must apply to the whole swarm: block or rewrite new tasks, route Slack channels, suppress follow-ups, change stalled-task remediation, guard tool calls, or react after a task or tool call finishes.
4
+
5
+ Do not use an extension for work that one task, one script, or one schedule can do.
6
+
7
+ ## Tools
8
+
9
+ `extension-install` and `extension-list`. They are deferred. Load them with your harness tool search before the first call.
10
+
11
+ `extension-install` validates the bundle (manifest, imports, typecheck against the hook contract) and stores it. Only a lead agent, an operator, or a dashboard user may install. A worker gets `Forbidden` from the tool. When you are a worker, write and validate the bundle, then hand it to your lead with `send-task` (include the manifest, the hooks file, and the config) and report that in your output. Do not call the REST install route with the shared API key to get around the role check. The stored extension stays disabled. An operator enables it from the dashboard (Settings, Extensions) or with `POST /api/extensions/{id}/enable`. Say this in your task report and give the extension name.
12
+
13
+ Installing a bundle with the same name and changed files stores a new version. The active version does not change until an operator activates it.
14
+
15
+ ## Get the contract before you write hooks
16
+
17
+ Fetch the generated type definitions and read them. Do not guess event names or field names.
18
+
19
+ ```bash
20
+ curl -s "$MCP_BASE_URL/api/extensions/type-defs" \
21
+ -H "X-Agent-ID: $AGENT_ID" -H "Authorization: Bearer ${AGENT_SWARM_API_KEY:-$API_KEY}"
22
+ ```
23
+
24
+ `$MCP_BASE_URL`, `$AGENT_ID`, and `$AGENT_SWARM_API_KEY` (or `$API_KEY`) are in every worker environment. The response is the `swarm-extension` module declaration: every event, its payload, and what a `modify` result may change.
25
+
26
+ ## Events
27
+
28
+ | Event | When | Result |
29
+ |---|---|---|
30
+ | `pre.task.create` | before any task is stored (REST, MCP, Slack, schedule, workflow, webhook, follow-up) | `block(reason)`, `modify({ priority, agentId, tags, description, ... })`, or nothing |
31
+ | `pre.task.followUp` | before the lead follow-up task for a finished worker task | `block`, `modify({ description, priority, agentId })`, or nothing |
32
+ | `pre.slack.route` | before a Slack message becomes a task | `modify({ target: { kind: "agent", agentId } })`, `{ kind: "lead" }`, `{ kind: "broadcast" }` |
33
+ | `pre.heartbeat.remediate` | after the heartbeat sweep finds a stalled task | `modify({ proposedAction: "record" | "fail" | "supersede-resume" })` |
34
+ | `pre.tool.call` | before an agent MCP tool call runs | `block(reason)` or `modify({ args })` |
35
+ | `post.task.created`, `post.task.completed`, `post.task.failed`, `post.task.cancelled`, `post.task.superseded`, `post.task.progress` | after the change is committed | none |
36
+ | `post.slack.message`, `post.tool.call` | after the message or tool call finished | none |
37
+
38
+ `event.origin` on `pre.task.create` tells where the task comes from: `rest`, `app`, `mcp`, `slack`, `schedule`, `workflow`, `webhook`, `followUp`, or `extension:<name>`.
39
+
40
+ ## Bundle shape
41
+
42
+ The bundle is a manifest plus a files map. Version 1 accepts one file, the `assets.hooks` TypeScript file, and only `runtime: "api"`.
43
+
44
+ ```json
45
+ {
46
+ "manifest": {
47
+ "name": "require-ticket-ref",
48
+ "description": "Blocks REST and MCP tasks that do not name a ticket",
49
+ "version": "1.0.0",
50
+ "runtime": "api",
51
+ "assets": { "hooks": "hooks.ts" }
52
+ },
53
+ "files": { "hooks.ts": "<file content>" },
54
+ "config": { "pattern": "DES-\\d+" }
55
+ }
56
+ ```
57
+
58
+ Rules for `hooks.ts`:
59
+
60
+ - Import only from `swarm-extension`, `zod`, and `stdlib`. Relative imports, other packages, and dynamic imports are rejected.
61
+ - Export the extension as `default`. Export `config` (a Zod schema) when the extension takes configuration. The install validates `config` against it.
62
+ - Return `block(reason)` or `modify(data)` from pre hooks. Return nothing to continue.
63
+ - Keep handlers fast. A handler is cancelled after 5 seconds. Five consecutive failures auto-disable the extension.
64
+ - Handlers run outside database transactions and must not assume ordering with other extensions. Use `priority` in `api.on(event, handler, { priority })` when order matters (lower runs first).
65
+
66
+ ## Minimal hooks file
67
+
68
+ ```ts
69
+ import { block, modify, type SwarmExtension } from "swarm-extension";
70
+ import { z } from "zod";
71
+
72
+ export const config = z.object({ pattern: z.string().default("DES-\\d+") });
73
+
74
+ const manifest = {
75
+ name: "require-ticket-ref",
76
+ description: "Blocks REST and MCP tasks that do not name a ticket",
77
+ version: "1.0.0",
78
+ runtime: "api",
79
+ assets: { hooks: "hooks.ts" },
80
+ config,
81
+ } as const;
82
+
83
+ const extension: SwarmExtension<typeof manifest> = (api) => {
84
+ api.on("pre.task.create", (event, ctx) => {
85
+ if (event.origin !== "rest" && event.origin !== "mcp") return;
86
+ if (new RegExp(ctx.config.pattern).test(event.description)) return;
87
+ return block(`Task must reference a ticket matching ${ctx.config.pattern}`);
88
+ });
89
+
90
+ api.on("post.task.completed", async (event, ctx) => {
91
+ await ctx.state.incr("completed");
92
+ ctx.log.info("task completed", { id: event.task.id });
93
+ });
94
+ };
95
+
96
+ export default extension;
97
+ ```
98
+
99
+ ## Context (`ctx`)
100
+
101
+ - `ctx.config`: the validated configuration.
102
+ - `ctx.state`: per-extension key-value store (`get`, `set`, `incr`, `del`).
103
+ - `ctx.swarm`: the swarm SDK. Call any script-exposed tool by name with underscores, for example `await ctx.swarm.slack_post({ channelId, message })` or `await ctx.swarm.task_send({ ... })`. Calls made from a hook carry the `ext:<name>` identity, which has lead privileges while the extension is enabled. Calls resolve with `{ success, status, data }` and do not throw on a tool error. Check `success` and throw when the hook must fail. The type definitions import `SwarmSdk` from `swarm-sdk`. Call the `script-query-types` tool (or `GET /api/scripts/type-defs`) to get `swarm-sdk.d.ts` with every method name and argument type before you use `ctx.swarm`.
104
+ - `ctx.log`: structured logger. Entries appear in the extension run log on the dashboard.
105
+ - `ctx.signal`: abort signal for the 5-second cap.
106
+
107
+ ## Verify
108
+
109
+ 1. Call `extension-list` and confirm the name, version, and `enabled: false`.
110
+ 2. Report the enable step. After an operator enables it, the dashboard run log shows every dispatch with its result (`continue`, `modify`, `block`, or `error`).
111
+ 3. Trigger the event once and confirm the effect (for example, a blocked REST task returns HTTP 422 with your reason).
112
+
113
+ ## Common mistakes
114
+
115
+ - Guessing event names. Fetch the type definitions.
116
+ - Using `import` from a package other than `swarm-extension`, `zod`, or `stdlib`.
117
+ - Returning a plain object instead of `block(...)` or `modify(...)`.
118
+ - Modifying fields the event does not allow. Read the `*Modify` type for that event.
119
+ - Expecting the extension to run after install. It runs only after an operator enables it.
120
+ - Blocking tasks from every origin. Check `event.origin` so schedules, workflows, and follow-ups keep working unless you mean to block them.
@@ -37,7 +37,7 @@ The swarm ships named scripts at global scope. Each one replaces a multi-step to
37
37
  | `task-context-gathering` | `{ taskId, queries: [...] }` | the task plus a deduplicated multi-query memory recall |
38
38
  | `smart-recall` | `{ queries: [...] }` | multi-query memory recall without the task |
39
39
  | `memory-dedup-check` | `{ text, threshold? }` | near-duplicates before you store a memory |
40
- | `delegate` | `{ agentName, task, routingReason, parentTaskId? }` | a subtask for an agent by name, returns `{ taskId }` |
40
+ | `delegate` | `{ agentName, task, routingReason, routingNote, parentTaskId? }` | a subtask for an agent by name, returns `{ taskId }` |
41
41
  | `wait-for-task` | `{ taskId }` | waits up to about 25 s for a terminal state, returns `{ done, status, output }`; call again while `done` is false |
42
42
  | `get-child-outputs` | `{ parentTaskId }` | every child with status and output |
43
43
  | `complete-task` | `{ taskId, output }` | finish a task from inside a script |
@@ -74,7 +74,7 @@ export default async function (args: z.infer<typeof argsSchema>, ctx: ScriptCont
74
74
  ### What `ctx` holds
75
75
 
76
76
  - `ctx.swarm.*`: the swarm SDK. `task_get`, `task_send`, `task_storeProgress`, `task_action`, `task_list`, `slack_reply`, `memory_search`, `memory_store`, `kv_get`, `kv_getOrNull`, `kv_set`, `kv_delete`, `kv_incr`, `kv_list`, `swarm_get`, `agent_info`, `db_query`, and more. `kv_getOrNull` returns the entry, `null` on a missing key, and throws on other errors.
77
- - `ctx.swarm.task_send` requires `routingReason` whenever `agentId` is present. Use `human_pinned` for an explicit/configured choice, `skill` for a role or specialization match, `continuity` for the same worker/session, `reroute_fault` for a fault handoff, or `overflow` for capacity/pool escalation. Omit both `agentId` and routing fields for the pool.
77
+ - `ctx.swarm.task_send` requires `routingReason` and `routingNote` whenever `agentId` is present. The note must explain the worker choice in at least 10 characters after trimming whitespace (maximum 200 characters). Use `human_pinned` for an explicit/configured choice, `skill` for a role or specialization match, `continuity` for the same worker/session, `reroute_fault` for a fault handoff, or `overflow` for capacity/pool escalation. Omit both `agentId` and routing fields for the pool.
78
78
  - `ctx.swarm.config`: `apiKey`, `agentId`, `mcpBaseUrl`, and `ctx.swarm.config.get("KEY")` for user config values. All are `Redacted` wrappers that stringify to `<redacted>`. Never unwrap one into a return value, a log line, or a request body you build by hand.
79
79
  - `ctx.api.<slug>` and `ctx.mcp.<slug>`: typed clients for registered connections. They exist only for registered connections. Introspect with `Object.keys(ctx.api ?? {})` and `Object.keys(ctx.mcp ?? {})`.
80
80
  - `ctx.stdlib`: `fetch`, `fetchJson` (retries, 30 s timeout), `grep`, `glob`, `table`, `Redacted`.
@@ -32,7 +32,7 @@ The swarm ships named scripts at global scope. Each one replaces a multi-step to
32
32
  | `task-context-gathering` | `{ taskId, queries: [...] }` | the task plus a deduplicated multi-query memory recall |
33
33
  | `smart-recall` | `{ queries: [...] }` | multi-query memory recall without the task |
34
34
  | `memory-dedup-check` | `{ text, threshold? }` | near-duplicates before you store a memory |
35
- | `delegate` | `{ agentName, task, routingReason, parentTaskId? }` | a subtask for an agent by name, returns `{ taskId }` |
35
+ | `delegate` | `{ agentName, task, routingReason, routingNote, parentTaskId? }` | a subtask for an agent by name, returns `{ taskId }` |
36
36
  | `wait-for-task` | `{ taskId }` | waits up to about 25 s for a terminal state, returns `{ done, status, output }`; call again while `done` is false |
37
37
  | `get-child-outputs` | `{ parentTaskId }` | every child with status and output |
38
38
  | `complete-task` | `{ taskId, output }` | finish a task from inside a script |
@@ -69,7 +69,7 @@ export default async function (args: z.infer<typeof argsSchema>, ctx: ScriptCont
69
69
  ### What `ctx` holds
70
70
 
71
71
  - `ctx.swarm.*`: the swarm SDK. `task_get`, `task_send`, `task_storeProgress`, `task_action`, `task_list`, `slack_reply`, `memory_search`, `memory_store`, `kv_get`, `kv_getOrNull`, `kv_set`, `kv_delete`, `kv_incr`, `kv_list`, `swarm_get`, `agent_info`, `db_query`, and more. `kv_getOrNull` returns the entry, `null` on a missing key, and throws on other errors.
72
- - `ctx.swarm.task_send` requires `routingReason` whenever `agentId` is present. Use `human_pinned` for an explicit/configured choice, `skill` for a role or specialization match, `continuity` for the same worker/session, `reroute_fault` for a fault handoff, or `overflow` for capacity/pool escalation. Omit both `agentId` and routing fields for the pool.
72
+ - `ctx.swarm.task_send` requires `routingReason` and `routingNote` whenever `agentId` is present. The note must explain the worker choice in at least 10 characters after trimming whitespace (maximum 200 characters). Use `human_pinned` for an explicit/configured choice, `skill` for a role or specialization match, `continuity` for the same worker/session, `reroute_fault` for a fault handoff, or `overflow` for capacity/pool escalation. Omit both `agentId` and routing fields for the pool.
73
73
  - `ctx.swarm.config`: `apiKey`, `agentId`, `mcpBaseUrl`, and `ctx.swarm.config.get("KEY")` for user config values. All are `Redacted` wrappers that stringify to `<redacted>`. Never unwrap one into a return value, a log line, or a request body you build by hand.
74
74
  - `ctx.api.<slug>` and `ctx.mcp.<slug>`: typed clients for registered connections. They exist only for registered connections. Introspect with `Object.keys(ctx.api ?? {})` and `Object.keys(ctx.mcp ?? {})`.
75
75
  - `ctx.stdlib`: `fetch`, `fetchJson` (retries, 30 s timeout), `grep`, `glob`, `table`, `Redacted`.
@@ -9,6 +9,6 @@
9
9
  "category": "workflows",
10
10
  "placeholders": [],
11
11
  "requires": [],
12
- "runAllSeedersCandidate": false,
12
+ "runAllSeedersCandidate": true,
13
13
  "tags": ["release-notes", "harness"]
14
14
  }
@@ -9,6 +9,6 @@
9
9
  "category": "workflows",
10
10
  "placeholders": ["GSC_PROPERTY"],
11
11
  "requires": ["gsc", "agentfs"],
12
- "runAllSeedersCandidate": false,
12
+ "runAllSeedersCandidate": true,
13
13
  "tags": ["gsc", "research", "content"]
14
14
  }
@@ -9,7 +9,7 @@
9
9
  "category": "workflows",
10
10
  "placeholders": ["LINEAR_PROJECT_ID"],
11
11
  "requires": ["linear"],
12
- "runAllSeedersCandidate": false,
12
+ "runAllSeedersCandidate": true,
13
13
  "tags": [
14
14
  "workflow",
15
15
  "linear",
@@ -9,6 +9,6 @@
9
9
  "category": "workflows",
10
10
  "placeholders": ["ORG_ID", "REPO_URL"],
11
11
  "requires": ["github"],
12
- "runAllSeedersCandidate": false,
12
+ "runAllSeedersCandidate": true,
13
13
  "tags": ["workflow", "release-notes", "context"]
14
14
  }
@@ -9,6 +9,6 @@
9
9
  "category": "workflows",
10
10
  "placeholders": ["REPO_URL"],
11
11
  "requires": ["github"],
12
- "runAllSeedersCandidate": false,
12
+ "runAllSeedersCandidate": true,
13
13
  "tags": ["workflow", "review", "iteration"]
14
14
  }