@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
@@ -86,6 +86,7 @@ describe("task tool ctx", () => {
86
86
  task: "ordinary direct assignment",
87
87
  agentId: lead.id,
88
88
  routingReason: "skill",
89
+ routingNote: "This test explicitly selects the target worker",
89
90
  offerMode: false,
90
91
  allowDuplicate: false,
91
92
  });
@@ -108,6 +109,7 @@ describe("task tool ctx", () => {
108
109
  task: "ordinary offer",
109
110
  agentId: lead.id,
110
111
  routingReason: "skill",
112
+ routingNote: "This test explicitly selects the target worker",
111
113
  offerMode: true,
112
114
  allowDuplicate: false,
113
115
  });
@@ -101,8 +101,8 @@ describe("getAllTasks / getTasksCount requestedByUserId filter", () => {
101
101
  // `GET /api/tasks` handler actually translates the `?requestedByUserId=none`
102
102
  // sentinel into `requestedByUserIdIsNull`, or that the omitted-param path
103
103
  // stays backwards compatible.
104
- const ROUTE_TEST_DB_PATH = "./test-tasks-requested-by-filter-route.sqlite";
105
- const ROUTE_API_KEY = "test-tasks-requested-by-filter-route";
104
+ const ROUTE_TEST_DB_PATH = "./example-test-tasks-requested-by-filter-route.sqlite";
105
+ const ROUTE_API_KEY = "example-test-tasks-requested-by-filter-route";
106
106
 
107
107
  async function removeDbFiles(path: string): Promise<void> {
108
108
  for (const suffix of ["", "-wal", "-shm"]) {
@@ -204,6 +204,14 @@ describe("initTelemetry", () => {
204
204
  const metadata = (captured as { metadata: Record<string, unknown> }).metadata;
205
205
  expect(metadata.organization_id).toBeUndefined();
206
206
  expect(metadata.organization_name).toBeUndefined();
207
+
208
+ // Dashboard config reloads update the env after telemetry initialized.
209
+ process.env.SWARM_ORG_NAME = " Acme Engineering ";
210
+ track({ event: "test.event", properties: {} });
211
+ await new Promise((r) => setTimeout(r, 0));
212
+ expect((captured as { metadata: Record<string, unknown> }).metadata.organization_name).toBe(
213
+ "Acme Engineering",
214
+ );
207
215
  });
208
216
 
209
217
  test("includes organization_id + organization_name when SWARM_ORG_* set", async () => {
@@ -756,11 +764,11 @@ describe("initTelemetry", () => {
756
764
 
757
765
  describe("_hasEmbeddingKey", () => {
758
766
  test("true when EMBEDDING_API_KEY is set", () => {
759
- expect(_hasEmbeddingKey({ EMBEDDING_API_KEY: "sk-embed" })).toBe(true);
767
+ expect(_hasEmbeddingKey({ EMBEDDING_API_KEY: "example-sk-embed" })).toBe(true);
760
768
  });
761
769
 
762
770
  test("true when OPENAI_API_KEY is set", () => {
763
- expect(_hasEmbeddingKey({ OPENAI_API_KEY: "sk-openai" })).toBe(true);
771
+ expect(_hasEmbeddingKey({ OPENAI_API_KEY: "example-sk-openai" })).toBe(true);
764
772
  });
765
773
 
766
774
  test("false when neither is set (onboard wizard only writes ANTHROPIC_API_KEY)", () => {
@@ -941,7 +949,7 @@ describe("initTelemetry", () => {
941
949
  });
942
950
 
943
951
  test("channels + embedding key all present", async () => {
944
- process.env.EMBEDDING_API_KEY = "sk-embed";
952
+ process.env.EMBEDDING_API_KEY = "example-sk-embed";
945
953
  process.env.SLACK_BOT_TOKEN = "xoxb-1";
946
954
  process.env.SLACK_APP_TOKEN = "xapp-1";
947
955
  process.env.AGENTMAIL_WEBHOOK_SECRET = "whsec_1";
@@ -378,7 +378,7 @@ describe("Tool Annotations & Classification", () => {
378
378
  // Includes 11 skill tools, 7 MCP server tools, reusable script tools, and the
379
379
  // native Kapso/WhatsApp tools (register/unregister number + send/reply message).
380
380
  expect(count).toBeGreaterThanOrEqual(45);
381
- expect(count).toBeLessThanOrEqual(141);
381
+ expect(count).toBeLessThanOrEqual(143);
382
382
  });
383
383
 
384
384
  test("core tools are fewer than deferred tools", () => {
@@ -165,6 +165,7 @@ describe("agent-id fields accept non-UUID agent ids", () => {
165
165
  const parsed = sendTaskInputSchema.parse({
166
166
  agentId: SLUG_WORKER_ID,
167
167
  routingReason: "skill",
168
+ routingNote: "This test explicitly selects the target worker",
168
169
  task: "do the thing",
169
170
  });
170
171
  expect(parsed.agentId).toBe(SLUG_WORKER_ID);
@@ -1,7 +1,11 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import * as z from "zod";
4
- import { createToolRegistrar } from "../tools/utils";
4
+ import {
5
+ createToolRegistrar,
6
+ finalizeSwarmToolResult,
7
+ markExtensionRequestOrigin,
8
+ } from "../tools/utils";
5
9
 
6
10
  describe("createToolRegistrar with no inputSchema", () => {
7
11
  test("handler receives requestInfo from meta when no inputSchema is defined", async () => {
@@ -117,4 +121,41 @@ describe("createToolRegistrar with no inputSchema", () => {
117
121
  });
118
122
  expect(result).toBeDefined();
119
123
  });
124
+
125
+ test("server-marked extension calls carry extension origin", async () => {
126
+ const server = new McpServer({ name: "test-extension-origin", version: "1.0.0" });
127
+ let callOrigin: string | undefined;
128
+ createToolRegistrar(server)(
129
+ "test-extension-origin-tool",
130
+ {
131
+ inputSchema: z.object({}),
132
+ outputSchema: z.looseObject({}),
133
+ },
134
+ async (_args, requestInfo) => {
135
+ callOrigin = requestInfo.callOrigin;
136
+ return { ok: true, message: "ok" };
137
+ },
138
+ );
139
+ const registeredTools = (server as Record<string, unknown>)._registeredTools as Record<
140
+ string,
141
+ { handler: (args: unknown, extra: unknown) => Promise<unknown> }
142
+ >;
143
+ const extra = markExtensionRequestOrigin({
144
+ sessionId: "extension",
145
+ requestInfo: { headers: { "x-agent-id": "extension-agent" } },
146
+ });
147
+
148
+ await registeredTools["test-extension-origin-tool"]!.handler({}, extra);
149
+ expect(callOrigin).toBe("extension");
150
+ });
151
+
152
+ test("extension calls bypass the model context ceiling", async () => {
153
+ const result = await finalizeSwarmToolResult(
154
+ "large-extension-result",
155
+ { ok: true, message: "ok", data: { value: "x".repeat(1_100_000) } },
156
+ { agentId: "extension-agent", callOrigin: "extension" },
157
+ );
158
+ expect(result.structuredContent?.truncation).toBeUndefined();
159
+ expect((result.structuredContent?.value as string).length).toBe(1_100_000);
160
+ });
120
161
  });
@@ -154,7 +154,7 @@ beforeAll(async () => {
154
154
  expires_in: 3600,
155
155
  scope: "read write",
156
156
  };
157
- if (includeRefreshToken) body.refresh_token = "rotated-refresh-token";
157
+ if (includeRefreshToken) body.refresh_token = "example-rotated-refresh-token";
158
158
  return Response.json(body);
159
159
  }
160
160
  return new Response("not found", { status: 404 });
@@ -227,7 +227,7 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
227
227
  // possible since the carve-out removal made the linear row user-manageable.
228
228
  await upsertOAuthApp("linear", {
229
229
  clientId: "pre-existing",
230
- clientSecret: "pre-existing-secret",
230
+ clientSecret: "example-pre-existing-secret",
231
231
  authorizeUrl: "https://linear.app/oauth/authorize",
232
232
  tokenUrl: "https://api.linear.app/oauth/token",
233
233
  redirectUri: `${appBase}/api/trackers/linear/callback`,
@@ -345,8 +345,8 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
345
345
  const authorization = await upsertAuthorization({
346
346
  appId,
347
347
  label: "default",
348
- accessToken: "stale-access",
349
- refreshToken: "old-refresh",
348
+ accessToken: "example-stale-access",
349
+ refreshToken: "example-old-refresh",
350
350
  expiresAt: new Date(Date.now() - 60_000).toISOString(),
351
351
  status: "active",
352
352
  });
@@ -366,7 +366,7 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
366
366
  body: JSON.stringify({
367
367
  provider: "linear",
368
368
  clientId: "generic-linear-client",
369
- clientSecret: "generic-linear-secret",
369
+ clientSecret: "example-generic-linear-secret",
370
370
  authorizeUrl: "https://linear.app/oauth/authorize",
371
371
  tokenUrl: "https://api.linear.app/oauth/token",
372
372
  scopes: ["read", "write"],
@@ -389,8 +389,8 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
389
389
  const authorization = await upsertAuthorization({
390
390
  appId,
391
391
  label: "default",
392
- accessToken: "initial-access",
393
- refreshToken: "linear-refresh",
392
+ accessToken: "example-initial-access",
393
+ refreshToken: "example-linear-refresh",
394
394
  expiresAt: new Date(Date.now() - 60_000).toISOString(),
395
395
  status: "active",
396
396
  });
@@ -34,7 +34,7 @@ describe("tracker-status (DB layer)", () => {
34
34
  test("returns token info after storing tokens", async () => {
35
35
  await upsertOAuthApp("linear", {
36
36
  clientId: "test-client",
37
- clientSecret: "test-secret",
37
+ clientSecret: "example-test-secret",
38
38
  authorizeUrl: "https://linear.app/oauth/authorize",
39
39
  tokenUrl: "https://api.linear.app/oauth/token",
40
40
  redirectUri: "http://localhost:3013/api/trackers/linear/callback",
@@ -42,8 +42,8 @@ describe("tracker-status (DB layer)", () => {
42
42
  });
43
43
 
44
44
  await storeOAuthTokens("linear", {
45
- accessToken: "test-token",
46
- refreshToken: "test-refresh",
45
+ accessToken: "example-test-token",
46
+ refreshToken: "example-test-refresh",
47
47
  expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(),
48
48
  scope: "read,write",
49
49
  });
@@ -169,6 +169,7 @@ describe("session-UI follow-up → Lead → onward delegation", () => {
169
169
  task: "please pick this up",
170
170
  agentId: differentWorkerId,
171
171
  routingReason: "human_pinned",
172
+ routingNote: "This test explicitly selects the target worker",
172
173
  allowDuplicate: true,
173
174
  },
174
175
  leadAgentId,
@@ -44,7 +44,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
44
44
  id: "app-linear",
45
45
  provider: "linear",
46
46
  clientId: "linear-client",
47
- clientSecret: "linear-client-secret",
47
+ clientSecret: "example-linear-client-secret",
48
48
  authorizeUrl: "https://linear.test/authorize",
49
49
  tokenUrl: "https://linear.test/token",
50
50
  redirectUri: "https://swarm.test/api/oauth/linear/callback",
@@ -60,7 +60,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
60
60
  id: "app-jira",
61
61
  provider: "jira",
62
62
  clientId: "jira-client",
63
- clientSecret: "jira-client-secret",
63
+ clientSecret: "example-jira-client-secret",
64
64
  authorizeUrl: "https://jira.test/authorize",
65
65
  tokenUrl: "https://jira.test/token",
66
66
  redirectUri: "https://swarm.test/api/oauth/jira/callback",
@@ -77,7 +77,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
77
77
  id: "app-vendor",
78
78
  provider: "vendor",
79
79
  clientId: "vendor-client",
80
- clientSecret: "vendor-client-secret",
80
+ clientSecret: "example-vendor-client-secret",
81
81
  authorizeUrl: "https://vendor.test/authorize",
82
82
  tokenUrl: "https://vendor.test/token",
83
83
  redirectUri: "https://swarm.test/api/oauth/vendor/callback",
@@ -422,9 +422,9 @@ describe("migration 117 unified OAuth storage", () => {
422
422
  )
423
423
  .get();
424
424
  expect(encryptedLinear?.clientSecretEncrypted).toBe(1);
425
- expect(encryptedLinear?.clientSecret).not.toBe("linear-client-secret");
425
+ expect(encryptedLinear?.clientSecret).not.toBe("example-linear-client-secret");
426
426
  expect(decryptSecret(encryptedLinear!.clientSecret, getEncryptionKey())).toBe(
427
- "linear-client-secret",
427
+ "example-linear-client-secret",
428
428
  );
429
429
  const encryptedAuthorization = database
430
430
  .query<{ accessToken: string; refreshToken: string | null; tokensEncrypted: number }, []>(
@@ -21,7 +21,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
21
21
  import { listenOnFreePort } from "./test-net";
22
22
 
23
23
  const TEST_DB_PATH = "./test-user-token-rest-auth.sqlite";
24
- const API_KEY = "test-api-key";
24
+ const API_KEY = "example-test-api-key";
25
25
  const ACTOR: IdentityActor = { kind: "operator", id: "op:test" };
26
26
 
27
27
  function createTestServer(): Server {
@@ -14,7 +14,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
14
14
  import { listenOnFreePort } from "./test-net";
15
15
 
16
16
  const TEST_DB_PATH = "./test-user-token-routes.sqlite";
17
- const API_KEY = "test-user-token-key";
17
+ const API_KEY = "example-test-user-token-key";
18
18
  const ORIGINAL_API_KEY = process.env.AGENT_SWARM_API_KEY;
19
19
 
20
20
  async function removeDbFiles(path: string): Promise<void> {
@@ -24,7 +24,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
24
24
  import { listenOnFreePort } from "./test-net";
25
25
 
26
26
  const TEST_DB_PATH = "./test-whoami-route.sqlite";
27
- const API_KEY = "test-api-key";
27
+ const API_KEY = "example-test-api-key";
28
28
  const ACTOR: IdentityActor = { kind: "operator", id: "op:test" };
29
29
 
30
30
  interface WhoamiBody {
@@ -37,7 +37,6 @@ const mockDeps: ExecutorDependencies = {
37
37
  // IDs for workflow prerequisites (set in beforeAll)
38
38
  let workflowId: string;
39
39
  let runId: string;
40
- let stepId1: string;
41
40
  let stepId2: string;
42
41
 
43
42
  // ─── Setup / Teardown ────────────────────────────────────────
@@ -64,14 +63,6 @@ beforeAll(async () => {
64
63
  const run = await createWorkflowRun({ id: crypto.randomUUID(), workflowId: wf.id });
65
64
  runId = run.id;
66
65
 
67
- const step1 = await createWorkflowRunStep({
68
- id: crypto.randomUUID(),
69
- runId: run.id,
70
- nodeId: "test-node-1",
71
- nodeType: "agent-task",
72
- });
73
- stepId1 = step1.id;
74
-
75
66
  const step2 = await createWorkflowRunStep({
76
67
  id: crypto.randomUUID(),
77
68
  runId: run.id,
@@ -159,7 +150,10 @@ describe("AgentTaskExecutor — workspace scoping", () => {
159
150
  expect(parsed.success).toBe(false);
160
151
  });
161
152
 
162
- test("execute() creates task with workspace fields forwarded", async () => {
153
+ test.each([
154
+ undefined,
155
+ "skill",
156
+ ] as const)("execute() forwards workspace fields and routing provenance for %s", async (routingReason) => {
163
157
  const executor = new AgentTaskExecutor(mockDeps);
164
158
  const worker = await createAgent({
165
159
  name: "Pinned workflow worker",
@@ -168,15 +162,22 @@ describe("AgentTaskExecutor — workspace scoping", () => {
168
162
  });
169
163
  const config = {
170
164
  agentId: worker.id,
165
+ routingReason,
171
166
  template: "List files in workspace",
172
167
  dir: "/workspace/repos/agent-swarm",
173
168
  vcsRepo: "desplega-ai/agent-swarm",
174
169
  model: "sonnet",
175
170
  };
171
+ const step = await createWorkflowRunStep({
172
+ id: crypto.randomUUID(),
173
+ runId,
174
+ nodeId: `routing-${routingReason ?? "default"}`,
175
+ nodeType: "agent-task",
176
+ });
176
177
  const meta: ExecutorMeta = {
177
178
  runId,
178
- stepId: stepId1,
179
- nodeId: "test-node-1",
179
+ stepId: step.id,
180
+ nodeId: step.nodeId,
180
181
  workflowId,
181
182
  dryRun: false,
182
183
  };
@@ -195,7 +196,8 @@ describe("AgentTaskExecutor — workspace scoping", () => {
195
196
  expect(task!.modelTier).toBe("regular");
196
197
  expect(task!.source).toBe("workflow");
197
198
  expect(task!.agentId).toBe(worker.id);
198
- expect(task!.routingReason).toBe("human_pinned");
199
+ expect(task!.routingReason).toBe(routingReason ?? "human_pinned");
200
+ expect(task!.routingSource).toBe(routingReason ? "declared" : "engine_default");
199
201
  });
200
202
 
201
203
  test("execute() creates task without workspace fields (backward compat)", async () => {
@@ -19,7 +19,7 @@ describe("workflow-ctx: ctx.swarm proxy tool name resolution", () => {
19
19
  const { ctx } = buildWorkflowCtx({
20
20
  runId: "test-run",
21
21
  agentId: "test-agent",
22
- apiKey: "test-key",
22
+ apiKey: "example-test-key",
23
23
  baseUrl: "http://localhost:9999",
24
24
  args: {},
25
25
  });
@@ -26,7 +26,7 @@ import { SKIP_SANDBOX_SPAWN_TESTS } from "./sandbox-spawn-test-helpers";
26
26
  const spawnDescribe = describe.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
27
27
 
28
28
  const TEST_DB_PATH = "./test-workflow-e2e.sqlite";
29
- const API_KEY = "test-workflow-e2e-key-1234567890";
29
+ const API_KEY = "example-test-workflow-e2e-key-1234567890";
30
30
 
31
31
  const noOpEmbeddingProvider = {
32
32
  name: "test/noop-workflow-e2e-embedding",
@@ -43,6 +43,8 @@ const skip = test.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
43
43
 
44
44
  const TEST_DB_PATH = "./test-workflow-engine-v2.sqlite";
45
45
 
46
+ const inputRef = (name: string): string => `input.${name}`;
47
+
46
48
  // ─── Test Executors ──────────────────────────────────────────
47
49
 
48
50
  class EchoExecutor extends BaseExecutor<typeof EchoExecutor.schema, typeof EchoExecutor.outSchema> {
@@ -1158,7 +1160,7 @@ describe("interpolateNodeConfig — script node", () => {
1158
1160
  test("an inputs alias pointing at workflow input is still interpolated into the script", () => {
1159
1161
  const node = {
1160
1162
  type: "script",
1161
- inputs: { token: "input.API_TOKEN" },
1163
+ inputs: { token: inputRef("API_TOKEN") },
1162
1164
  config: { runtime: "bash", script: "curl -H 'Authorization: {{token}}' https://x" },
1163
1165
  };
1164
1166
  const ctx = { input: { API_TOKEN: "tok-123" }, token: "tok-123" };
@@ -594,8 +594,8 @@ describe("ScriptExecutor", () => {
594
594
 
595
595
  skip("child process never inherits the server's secrets — env is scrubbed, not passed through", async () => {
596
596
  const savedKey = process.env.AGENT_SWARM_API_KEY;
597
- process.env.AGENT_SWARM_API_KEY = "super-secret-operator-bearer";
598
- process.env.SOME_OTHER_SERVER_SECRET = "also-should-not-leak";
597
+ process.env.AGENT_SWARM_API_KEY = "example-super-secret-operator-bearer";
598
+ process.env.SOME_OTHER_SERVER_SECRET = "example-also-should-not-leak";
599
599
  try {
600
600
  const result = await executor.run(
601
601
  input(
@@ -41,6 +41,8 @@ import { listenOnFreePort } from "./test-net";
41
41
 
42
42
  const TEST_DB_PATH = "./test-workflow-http-v2.sqlite";
43
43
 
44
+ const secretRef = (name: string): string => `secret.${name}`;
45
+
44
46
  // ─── Test Server ─────────────────────────────────────────────
45
47
 
46
48
  function createTestServer(): Server {
@@ -201,10 +203,10 @@ describe("Workflow HTTP API v2", () => {
201
203
  name: "full-schema-workflow",
202
204
  description: "test",
203
205
  definition: simpleDefinition(),
204
- triggers: [{ type: "webhook", hmacSecret: "secret-123" }],
206
+ triggers: [{ type: "webhook", hmacSecret: "example-secret-123" }],
205
207
  cooldown: { minutes: 30 },
206
208
  // biome-ignore lint/suspicious/noTemplateCurlyInString: intentional — this is the input resolution syntax
207
- input: { apiKey: "${API_KEY}", secret: "secret.MY_SECRET", literal: "hello" },
209
+ input: { apiKey: "${API_KEY}", secret: secretRef("MY_SECRET"), literal: "hello" },
208
210
  }),
209
211
  });
210
212
 
@@ -480,7 +482,7 @@ describe("Workflow HTTP API v2", () => {
480
482
  method: "PUT",
481
483
  headers,
482
484
  body: JSON.stringify({
483
- triggers: [{ type: "webhook", hmacSecret: "new-secret" }],
485
+ triggers: [{ type: "webhook", hmacSecret: "example-new-secret" }],
484
486
  cooldown: { seconds: 30 },
485
487
  input: { key: "value" },
486
488
  params: { REPO_URL: "acme/widgets" },
@@ -921,11 +923,11 @@ describe("Workflow HTTP API v2", () => {
921
923
  describe("POST /api/webhooks/:workflowId", () => {
922
924
  test("valid HMAC returns 201", async () => {
923
925
  const workflow = await createTestWorkflow({
924
- triggers: [{ type: "webhook", hmacSecret: "test-secret" }],
926
+ triggers: [{ type: "webhook", hmacSecret: "example-test-secret" }],
925
927
  });
926
928
 
927
929
  const body = '{"event":"test"}';
928
- const hmac = crypto.createHmac("sha256", "test-secret");
930
+ const hmac = crypto.createHmac("sha256", "example-test-secret");
929
931
  hmac.update(body);
930
932
  const sig = `sha256=${hmac.digest("hex")}`;
931
933
 
@@ -944,7 +946,7 @@ describe("Workflow HTTP API v2", () => {
944
946
 
945
947
  test("invalid HMAC returns 401", async () => {
946
948
  const workflow = await createTestWorkflow({
947
- triggers: [{ type: "webhook", hmacSecret: "test-secret" }],
949
+ triggers: [{ type: "webhook", hmacSecret: "example-test-secret" }],
948
950
  });
949
951
 
950
952
  const res = await fetch(`${baseUrl}/api/webhooks/${workflow.id}`, {
@@ -26,6 +26,8 @@ import {
26
26
 
27
27
  const TEST_DB_PATH = "./test-workflow-input-redaction.sqlite";
28
28
 
29
+ const secretRef = (name: string): string => `secret.${name}`;
30
+
29
31
  // Captures the input it was invoked with so we can assert what the executor
30
32
  // actually receives (real value, not redacted).
31
33
  class CaptureExecutor extends BaseExecutor<
@@ -52,7 +54,7 @@ class CaptureExecutor extends BaseExecutor<
52
54
 
53
55
  describe("getSecretInputKeys", () => {
54
56
  test("flags secret.* references", () => {
55
- const keys = getSecretInputKeys({ GITHUB_TOKEN: "secret.GITHUB_TOKEN" });
57
+ const keys = getSecretInputKeys({ GITHUB_TOKEN: secretRef("GITHUB_TOKEN") });
56
58
  expect(keys.has("GITHUB_TOKEN")).toBe(true);
57
59
  expect(keys.size).toBe(1);
58
60
  });
@@ -104,7 +106,7 @@ describe("redactSecretsForStorage", () => {
104
106
  test("redacts only declared secret keys in ctx.input", () => {
105
107
  const ctx = {
106
108
  trigger: { topic: "tuxedo" },
107
- input: { GITHUB_TOKEN: "ghp_real_value_xxx", branch: "main" },
109
+ input: { GITHUB_TOKEN: "example-ghp_real_value_xxx", branch: "main" },
108
110
  };
109
111
  const out = redactSecretsForStorage(ctx, new Set(["GITHUB_TOKEN"]));
110
112
  expect((out.input as Record<string, unknown>).GITHUB_TOKEN).toBe(REDACTED_SECRET_VALUE);
@@ -114,9 +116,9 @@ describe("redactSecretsForStorage", () => {
114
116
  });
115
117
 
116
118
  test("does not mutate the original ctx (executor still sees real value)", () => {
117
- const ctx = { input: { GITHUB_TOKEN: "ghp_real" } };
119
+ const ctx = { input: { GITHUB_TOKEN: "example-ghp_real" } };
118
120
  redactSecretsForStorage(ctx, new Set(["GITHUB_TOKEN"]));
119
- expect((ctx.input as Record<string, unknown>).GITHUB_TOKEN).toBe("ghp_real");
121
+ expect((ctx.input as Record<string, unknown>).GITHUB_TOKEN).toBe("example-ghp_real");
120
122
  });
121
123
 
122
124
  test("no-ops when ctx has no input block", () => {
@@ -187,7 +189,7 @@ describe("end-to-end — workflow step persistence redacts secrets", () => {
187
189
  definition: def,
188
190
  triggers: [],
189
191
  input: {
190
- GITHUB_TOKEN: "secret.TEST_REDACTION_GITHUB_TOKEN",
192
+ GITHUB_TOKEN: secretRef("TEST_REDACTION_GITHUB_TOKEN"),
191
193
  plain: "not-a-secret",
192
194
  },
193
195
  });
@@ -588,7 +588,7 @@ describe("Workflow Integration — I/O Schemas, Convergence, TriggerSchema (Phas
588
588
  };
589
589
 
590
590
  // Set env var for input resolution
591
- process.env.TEST_INTEG_API_KEY = "secret123";
591
+ process.env.TEST_INTEG_API_KEY = "example-secret123";
592
592
  const workflow = await makeWorkflow(def, {
593
593
  // biome-ignore lint/suspicious/noTemplateCurlyInString: testing env var syntax
594
594
  input: { API_KEY: "${TEST_INTEG_API_KEY}" },
@@ -600,7 +600,7 @@ describe("Workflow Integration — I/O Schemas, Convergence, TriggerSchema (Phas
600
600
  expect(run!.status).toBe("completed");
601
601
 
602
602
  const ctx = run!.context as Record<string, unknown>;
603
- expect(ctx.step1).toEqual({ echo: "env=secret123" });
603
+ expect(ctx.step1).toEqual({ echo: "env=example-secret123" });
604
604
  });
605
605
  });
606
606
 
@@ -17,11 +17,11 @@ describe("resolveWorkflowLlmConfig", () => {
17
17
 
18
18
  test("routes OpenAI credentials to the SDK default endpoint", async () => {
19
19
  const config = await resolveWorkflowLlmConfig(undefined, {
20
- OPENAI_API_KEY: "sk-openai-test",
20
+ OPENAI_API_KEY: "example-sk-openai-test",
21
21
  });
22
22
 
23
23
  expect(config).toEqual({
24
- apiKey: "sk-openai-test",
24
+ apiKey: "example-sk-openai-test",
25
25
  baseURL: undefined,
26
26
  model: "gpt-5.4-mini",
27
27
  });
@@ -32,7 +32,7 @@ describe("resolveWorkflowLlmConfig", () => {
32
32
  process.env.MEMORY_RATER_MODEL = "openrouter/anthropic/claude-sonnet-4-5";
33
33
  try {
34
34
  const config = await resolveWorkflowLlmConfig(undefined, {
35
- OPENAI_API_KEY: "sk-openai-test",
35
+ OPENAI_API_KEY: "example-sk-openai-test",
36
36
  });
37
37
  expect(config.model).toBe("gpt-5.4-mini");
38
38
  } finally {
@@ -43,7 +43,7 @@ describe("resolveWorkflowLlmConfig", () => {
43
43
 
44
44
  test("preserves an explicit provider-compatible model", async () => {
45
45
  const config = await resolveWorkflowLlmConfig("openai/gpt-5.4", {
46
- OPENAI_API_KEY: "sk-openai-test",
46
+ OPENAI_API_KEY: "example-sk-openai-test",
47
47
  });
48
48
 
49
49
  expect(config.model).toBe("gpt-5.4");
@@ -51,7 +51,7 @@ describe("resolveWorkflowLlmConfig", () => {
51
51
 
52
52
  test("rejects credential kinds without an OpenAI-compatible endpoint", async () => {
53
53
  await expect(
54
- resolveWorkflowLlmConfig(undefined, { ANTHROPIC_API_KEY: "sk-ant-test" }),
54
+ resolveWorkflowLlmConfig(undefined, { ANTHROPIC_API_KEY: "example-sk-ant-test" }),
55
55
  ).rejects.toThrow("do not support the resolved anthropic credential yet");
56
56
  });
57
57
  });
@@ -500,7 +500,7 @@ describe("Workflow Registry & Definition (Phase 1)", () => {
500
500
  { id: "b", type: "notify", config: { channel: "swarm", template: "done" } },
501
501
  ],
502
502
  },
503
- triggers: [{ type: "webhook", hmacSecret: "test-secret" }],
503
+ triggers: [{ type: "webhook", hmacSecret: "example-test-secret" }],
504
504
  cooldown: { hours: 1 },
505
505
  input: { apiKey: envVarRef },
506
506
  });
@@ -35,7 +35,7 @@ import { SKIP_SANDBOX_SPAWN_TESTS } from "./sandbox-spawn-test-helpers";
35
35
  const skip = test.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
36
36
 
37
37
  const TEST_DB_PATH = "./test-workflow-swarm-script.sqlite";
38
- const API_KEY = "test-workflow-swarm-script-key-1234567890";
38
+ const API_KEY = "example-test-workflow-swarm-script-key-1234567890";
39
39
 
40
40
  const noOpEmbeddingProvider = {
41
41
  name: "test/noop-workflow-script-embedding",