@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
@@ -3,6 +3,7 @@ import { unlink } from "node:fs/promises";
3
3
  import { createServer as createHttpServer, type Server } from "node:http";
4
4
  import { initAgentMail, resetAgentMail } from "../agentmail";
5
5
  import { closeDb, deleteSwarmConfig, getDbClient, initDb, upsertSwarmConfig } from "../be/db";
6
+ import { getEmbeddingProvider, resetEmbeddingProvider } from "../be/memory";
6
7
  import { initGitHub, resetGitHub } from "../github";
7
8
  import {
8
9
  __resetInjectedEnvTracking,
@@ -10,6 +11,7 @@ import {
10
11
  _resetAutoReloadForTests,
11
12
  flushPendingIntegrationsReload,
12
13
  loadGlobalConfigsIntoEnv,
14
+ reloadGlobalConfigsAndIntegrations,
13
15
  scheduleIntegrationsReload,
14
16
  } from "../http/core";
15
17
  import { isOriginAllowedForCredentials } from "../http/utils";
@@ -262,6 +264,48 @@ describe("reload-config", () => {
262
264
  expect(res.status).toBe(404);
263
265
  });
264
266
 
267
+ // Regression: EMBEDDING_API_KEY / OPENAI_API_KEY used to be read once at
268
+ // OpenAIEmbeddingProvider construction and never revisited, so a key set
269
+ // (or rotated) via the dashboard/API stayed inert until the API process
270
+ // restarted (customer-reported, Jan Carbonell 2026-09-16: valid key,
271
+ // reload reported it loaded, embeddings still stayed off). Assert the
272
+ // full path: no key -> provider unconfigured -> config write + reload ->
273
+ // provider live, without a restart.
274
+ test("reload turns embeddings on without a restart once a key lands via config", async () => {
275
+ const originalEmbeddingKey = process.env.EMBEDDING_API_KEY;
276
+ const originalOpenAiKey = process.env.OPENAI_API_KEY;
277
+ delete process.env.EMBEDDING_API_KEY;
278
+ delete process.env.OPENAI_API_KEY;
279
+ resetEmbeddingProvider();
280
+ expect(getEmbeddingProvider().isConfigured()).toBe(false);
281
+
282
+ const config = await upsertSwarmConfig({
283
+ scope: "global",
284
+ key: "EMBEDDING_API_KEY",
285
+ value: "sk-test-not-a-real-key",
286
+ isSecret: true,
287
+ });
288
+
289
+ try {
290
+ const result = await reloadGlobalConfigsAndIntegrations();
291
+ expect(result.keysUpdated).toContain("EMBEDDING_API_KEY");
292
+ expect(result.integrationsReinitialized).toContain("embeddings");
293
+ expect(getEmbeddingProvider().isConfigured()).toBe(true);
294
+ } finally {
295
+ await deleteSwarmConfig(config.id);
296
+ delete process.env.EMBEDDING_API_KEY;
297
+ if (originalOpenAiKey === undefined) {
298
+ delete process.env.OPENAI_API_KEY;
299
+ } else {
300
+ process.env.OPENAI_API_KEY = originalOpenAiKey;
301
+ }
302
+ resetEmbeddingProvider();
303
+ if (originalEmbeddingKey !== undefined) {
304
+ process.env.EMBEDDING_API_KEY = originalEmbeddingKey;
305
+ }
306
+ }
307
+ });
308
+
265
309
  // Regression: injection used to be one-way. Deleting a global row left the
266
310
  // previously-injected value live in process.env until the process restarted,
267
311
  // so "reset to default" in the dashboard silently did nothing.
@@ -430,7 +474,7 @@ describe("auto-reload debouncer", () => {
430
474
  const testKey = `__TEST_OVERRIDE_LIVE_${Date.now()}`;
431
475
  process.env[testKey] = "shipped-by-deploy";
432
476
 
433
- // Pre-existing env should win at startup, but reload uses override=true.
477
+ // Pre-existing env set manually here; reload (and boot) use override=true.
434
478
  await upsertSwarmConfig({ scope: "global", key: testKey, value: "from-config" });
435
479
  scheduleIntegrationsReload(20);
436
480
 
@@ -101,7 +101,7 @@ const EXPECTED_INVENTORY: InventoryEntry[] = [
101
101
  file: "src/tools/send-task.ts",
102
102
  owner: "sendTaskHandler",
103
103
  syntax: "PropertyAssignment",
104
- count: 3,
104
+ count: 1,
105
105
  kind: "producer",
106
106
  dispatchProof: {
107
107
  file: "src/tests/task-tools-ctx.test.ts",
@@ -13,7 +13,12 @@ const ROUTING_REASONS = [
13
13
  describe("send-task routing decision input", () => {
14
14
  test.each(ROUTING_REASONS)("accepts routingReason %s", (routingReason) => {
15
15
  expect(
16
- sendTaskInputSchema.safeParse({ task: "delegate", agentId: "worker", routingReason }).success,
16
+ sendTaskInputSchema.safeParse({
17
+ task: "delegate",
18
+ agentId: "worker",
19
+ routingReason,
20
+ routingNote: "Owns this code path",
21
+ }).success,
17
22
  ).toBe(true);
18
23
  });
19
24
 
@@ -23,6 +28,7 @@ describe("send-task routing decision input", () => {
23
28
  task: "delegate",
24
29
  agentId: "worker",
25
30
  routingReason: "round_robin",
31
+ routingNote: "Owns this code path",
26
32
  }).success,
27
33
  ).toBe(false);
28
34
  });
@@ -53,6 +59,52 @@ describe("send-task routing decision input", () => {
53
59
  ).toBe(false);
54
60
  });
55
61
 
62
+ test.each([
63
+ undefined,
64
+ "",
65
+ " ",
66
+ "123456789",
67
+ " 123456789 ",
68
+ ])("rejects direct assignment and offers with a missing or short note: %s", (routingNote) => {
69
+ for (const offerMode of [false, true]) {
70
+ const result = sendTaskInputSchema.safeParse({
71
+ task: "delegate",
72
+ agentId: "worker",
73
+ routingReason: "skill",
74
+ routingNote,
75
+ offerMode,
76
+ });
77
+ expect(result.success).toBe(false);
78
+ if (!result.success) expect(result.error.issues[0]?.path).toEqual(["routingNote"]);
79
+ }
80
+ });
81
+
82
+ test("accepts exactly 10 trimmed characters and does not require a note for implicit routing", () => {
83
+ expect(
84
+ sendTaskInputSchema.safeParse({
85
+ task: "delegate",
86
+ agentId: "worker",
87
+ routingReason: "skill",
88
+ routingNote: " 1234567890 ",
89
+ }).success,
90
+ ).toBe(true);
91
+ expect(sendTaskInputSchema.safeParse({ task: "pool" }).success).toBe(true);
92
+ expect(
93
+ sendTaskInputSchema.safeParse({ task: "continue", parentTaskId: crypto.randomUUID() })
94
+ .success,
95
+ ).toBe(true);
96
+ });
97
+
98
+ test("handler rejects a missing note before any direct-call write", async () => {
99
+ const result = await sendTaskHandler({ kind: "owner", agentId: "sender" }, {
100
+ task: "delegate",
101
+ agentId: "worker",
102
+ routingReason: "skill",
103
+ } as never);
104
+ expect(result.ok).toBe(false);
105
+ expect(result.message).toContain("routingNote is required");
106
+ });
107
+
56
108
  test("handler rejects direct callers that bypass schema parsing", async () => {
57
109
  const result = await sendTaskHandler({ kind: "owner", agentId: "sender" }, {
58
110
  task: "delegate",
@@ -77,13 +129,34 @@ test("the delegate script requires the caller's reason and forwards it without r
77
129
  },
78
130
  };
79
131
  expect((await delegate({ agentName: "Worker", task: "work" }, ctx)).ok).toBe(false);
132
+ expect(
133
+ (await delegate({ agentName: "Worker", task: "work", routingReason: "skill" }, ctx)).ok,
134
+ ).toBe(false);
135
+ expect(
136
+ (
137
+ await delegate(
138
+ { agentName: "Worker", task: "work", routingReason: "skill", routingNote: " 123456789 " },
139
+ ctx,
140
+ )
141
+ ).ok,
142
+ ).toBe(false);
80
143
  expect(sent).toHaveLength(0);
81
144
  const result = await delegate(
82
- { agentName: "Worker", task: "work", routingReason: "continuity", routingNote: "same PR" },
145
+ {
146
+ agentName: "Worker",
147
+ task: "work",
148
+ routingReason: "continuity",
149
+ routingNote: "same PR and worker",
150
+ },
83
151
  ctx,
84
152
  );
85
153
  expect(result.ok).toBe(true);
86
154
  expect(sent).toEqual([
87
- { agentId: "worker", task: "work", routingReason: "continuity", routingNote: "same PR" },
155
+ {
156
+ agentId: "worker",
157
+ task: "work",
158
+ routingReason: "continuity",
159
+ routingNote: "same PR and worker",
160
+ },
88
161
  ]);
89
162
  });
@@ -1,11 +1,15 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
  import ts from "typescript";
3
3
 
4
- const TASK_CREATORS = new Set(["createTaskExtended", "createTaskWithSiblingAwareness"]);
4
+ const TASK_CREATORS = new Set([
5
+ "createTaskExtended",
6
+ "createTaskWithSiblingAwareness",
7
+ "createSlackTaskWithFiles",
8
+ ]);
5
9
 
6
10
  type Violation = { file: string; line: number; creator: string };
7
11
 
8
- async function assignedCreatorsWithoutReason(): Promise<Violation[]> {
12
+ async function creatorsWithoutRoutingMetadata(): Promise<Violation[]> {
9
13
  const violations: Violation[] = [];
10
14
  const glob = new Bun.Glob("src/**/*.ts");
11
15
 
@@ -32,8 +36,9 @@ async function assignedCreatorsWithoutReason(): Promise<Violation[]> {
32
36
  ),
33
37
  );
34
38
  if (
35
- (propertyNames.has("agentId") || propertyNames.has("offeredTo")) &&
36
- !propertyNames.has("routingReason")
39
+ ((propertyNames.has("agentId") || propertyNames.has("offeredTo")) &&
40
+ !propertyNames.has("routingReason")) ||
41
+ (propertyNames.has("routingReason") && !propertyNames.has("routingSource"))
37
42
  ) {
38
43
  const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
39
44
  violations.push({ file, line: line + 1, creator });
@@ -49,7 +54,7 @@ async function assignedCreatorsWithoutReason(): Promise<Violation[]> {
49
54
  }
50
55
 
51
56
  describe("routing reason production inventory", () => {
52
- test("every direct assigned/offer creator declares its reason at the call site", async () => {
53
- expect(await assignedCreatorsWithoutReason()).toEqual([]);
57
+ test("every assigned/offer creator records its reason and provenance at the call site", async () => {
58
+ expect(await creatorsWithoutRoutingMetadata()).toEqual([]);
54
59
  });
55
60
  });
@@ -0,0 +1,53 @@
1
+ import { Database } from "bun:sqlite";
2
+ import { describe, expect, test } from "bun:test";
3
+ import { runMigrations } from "../be/migrations/runner";
4
+ import { CreateTaskOptionsSchema, RoutingSourceSchema } from "../types";
5
+
6
+ const migration = await Bun.file(
7
+ new URL("../be/migrations/154_routing_source.sql", import.meta.url),
8
+ ).text();
9
+
10
+ describe("routing provenance migration", () => {
11
+ test("preserves historical reasons with unknown provenance and checks new sources", () => {
12
+ const database = new Database(":memory:");
13
+ try {
14
+ database.exec(`CREATE TABLE agent_tasks (id TEXT PRIMARY KEY, routing_reason TEXT);
15
+ INSERT INTO agent_tasks VALUES ('legacy', 'skill');`);
16
+ database.exec(migration);
17
+ expect(database.query("SELECT * FROM agent_tasks").get()).toEqual({
18
+ id: "legacy",
19
+ routing_reason: "skill",
20
+ routing_source: null,
21
+ });
22
+ for (const routingSource of RoutingSourceSchema.options) {
23
+ database.run("INSERT INTO agent_tasks VALUES (?, 'skill', ?)", [
24
+ routingSource,
25
+ routingSource,
26
+ ]);
27
+ expect(CreateTaskOptionsSchema.parse({ routingSource }).routingSource).toBe(routingSource);
28
+ }
29
+ expect(() =>
30
+ database.run("INSERT INTO agent_tasks VALUES ('invalid', 'skill', 'guessed')"),
31
+ ).toThrow();
32
+ expect(CreateTaskOptionsSchema.safeParse({ routingSource: "guessed" }).success).toBe(false);
33
+ } finally {
34
+ database.close();
35
+ }
36
+ });
37
+
38
+ test("applies 154 on a fresh database and reruns cleanly", () => {
39
+ const database = new Database(":memory:");
40
+ try {
41
+ runMigrations(database);
42
+ runMigrations(database);
43
+ expect(database.query("SELECT name FROM _migrations WHERE version = 154").all()).toEqual([
44
+ { name: "154_routing_source" },
45
+ ]);
46
+ expect(database.query("PRAGMA table_info(agent_tasks)").all()).toContainEqual(
47
+ expect.objectContaining({ name: "routing_source", notnull: 0, dflt_value: null }),
48
+ );
49
+ } finally {
50
+ database.close();
51
+ }
52
+ });
53
+ });
@@ -21,7 +21,7 @@ import { listenOnFreePort } from "./test-net";
21
21
  */
22
22
 
23
23
  const AGENT_ID = "9b2c4a1e-6d3f-4a55-8f27-1c0e7b5a4d90";
24
- const API_KEY = "test-swarm-key";
24
+ const API_KEY = "example-test-swarm-key";
25
25
  const AGENT_FS_KEY = "af_live_key";
26
26
 
27
27
  type FakeApiState = {
@@ -11,7 +11,7 @@ import {
11
11
  import { listenOnFreePort } from "./test-net";
12
12
 
13
13
  let API_URL = "";
14
- const API_KEY = "test-key";
14
+ const API_KEY = "example-test-key";
15
15
 
16
16
  // In-memory task store for the mock server
17
17
  const mockTasks: Record<string, TaskContextForPreamble> = {};
@@ -71,7 +71,7 @@ describe("deployment resume context", () => {
71
71
  mimeType: "text/plain",
72
72
  sizeBytes: 42,
73
73
  });
74
- const tasks = await getPausedTasksFromAPI({ apiUrl, apiKey: "test-key", agentId });
74
+ const tasks = await getPausedTasksFromAPI({ apiUrl, apiKey: "example-test-key", agentId });
75
75
  const paused = tasks.find((row) => row.id === task.id);
76
76
  expect(paused).toBeDefined();
77
77
  if (!paused) throw new Error("Paused task missing");
@@ -48,7 +48,7 @@ function resetMocks() {
48
48
  function makeConfig(): ApiConfig {
49
49
  return {
50
50
  apiUrl: "http://runner-fallback.test",
51
- apiKey: "test-key",
51
+ apiKey: "example-test-key",
52
52
  agentId: "test-agent-id",
53
53
  };
54
54
  }
@@ -32,7 +32,7 @@ async function runFixture(scenario: string): Promise<FixtureResult> {
32
32
  PATH: process.env.PATH,
33
33
  HOME: directory,
34
34
  AGENT_ID: "11111111-1111-4111-8111-111111111111",
35
- API_KEY: "fixture-key",
35
+ API_KEY: "example-fixture-key",
36
36
  MCP_BASE_URL: "http://runner.invalid",
37
37
  HARNESS_PROVIDER: "pi",
38
38
  CRED_CHECK_DISABLE: "1",
@@ -126,7 +126,7 @@ describe("refreshSkillsIfChanged", () => {
126
126
  return {
127
127
  apiUrl: baseUrl,
128
128
  swarmUrl: "app.agent-swarm.dev",
129
- apiKey: "test-key",
129
+ apiKey: "example-test-key",
130
130
  agentId: "agent-1",
131
131
  role: "worker",
132
132
  };
@@ -68,7 +68,7 @@ import { SKIP_SANDBOX_SPAWN_TESTS } from "./sandbox-spawn-test-helpers";
68
68
  const skip = test.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
69
69
 
70
70
  const TEST_DB_PATH = "./test-schedule-target-type.sqlite";
71
- const API_KEY = "test-schedule-target-type-key-1234567890";
71
+ const API_KEY = "example-test-schedule-target-type-key-1234567890";
72
72
 
73
73
  const noOpEmbeddingProvider = {
74
74
  name: "test/noop-schedule-target-type-embedding",
@@ -555,7 +555,7 @@ describe("dispatchScheduleTarget — workflow target", () => {
555
555
  );
556
556
  expect(after?.count).toBe(before?.count);
557
557
  expect(updated?.enabled).toBe(true);
558
- expect(updated?.lastRunAt).toBeUndefined();
558
+ expect(updated?.lastRunAt).toBeDefined();
559
559
  expect(updated?.consecutiveErrors).toBe(0);
560
560
  expect(updated?.lastErrorMessage).toBe("needs_setup: params=[REPO_URL] integrations=[]");
561
561
  expect(new Date(updated!.nextRunAt!).getTime()).toBeGreaterThan(Date.now());
@@ -654,7 +654,7 @@ describe("dispatchScheduleTarget — automation preflight", () => {
654
654
  expect(second.lastErrorMessage).toBe("needs_setup: params=[REPO_URL] integrations=[]");
655
655
  expect(second.consecutiveErrors).toBe(0);
656
656
  expect(second.enabled).toBe(true);
657
- expect(second.lastRunAt).toBeUndefined();
657
+ expect(second.lastRunAt).toBeDefined();
658
658
  expect(new Date(second.nextRunAt!).getTime()).toBeGreaterThan(Date.now());
659
659
  });
660
660
 
@@ -399,13 +399,14 @@ describe("Scheduled Tasks Integration", () => {
399
399
 
400
400
  // Find the created task
401
401
  const createdTask = (await getDbClient().get(
402
- "SELECT *, routing_reason AS routingReason FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1",
402
+ "SELECT *, routing_reason AS routingReason, routing_source AS routingSource FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1",
403
403
  [schedule.taskTemplate!],
404
- )) as { agentId: string; routingReason: string; status: string };
404
+ )) as { agentId: string; routingReason: string; routingSource: string; status: string };
405
405
 
406
406
  expect(createdTask).toBeDefined();
407
407
  expect(createdTask.agentId).toBe(targetAgent.id);
408
408
  expect(createdTask.routingReason).toBe("human_pinned");
409
+ expect(createdTask.routingSource).toBe("engine_default");
409
410
  expect(createdTask.status).toBe("pending"); // Should be pending when assigned to agent
410
411
  });
411
412
 
@@ -421,13 +422,19 @@ describe("Scheduled Tasks Integration", () => {
421
422
 
422
423
  // Find the created task
423
424
  const createdTask = (await getDbClient().get(
424
- "SELECT *, routing_reason AS routingReason FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1",
425
+ "SELECT *, routing_reason AS routingReason, routing_source AS routingSource FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1",
425
426
  [schedule.taskTemplate!],
426
- )) as { agentId: string | null; routingReason: string | null; status: string };
427
+ )) as {
428
+ agentId: string | null;
429
+ routingReason: string | null;
430
+ routingSource: string | null;
431
+ status: string;
432
+ };
427
433
 
428
434
  expect(createdTask).toBeDefined();
429
435
  expect(createdTask.agentId).toBeNull();
430
436
  expect(createdTask.routingReason).toBeNull();
437
+ expect(createdTask.routingSource).toBeNull();
431
438
  expect(createdTask.status).toBe("unassigned");
432
439
  });
433
440
 
@@ -531,7 +538,7 @@ describe("Scheduled Tasks Integration", () => {
531
538
 
532
539
  // Find the created task
533
540
  const createdTask = (await getDbClient().get(
534
- "SELECT *, routing_reason AS routingReason FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1",
541
+ "SELECT *, routing_reason AS routingReason, routing_source AS routingSource FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1",
535
542
  [schedule.taskTemplate!],
536
543
  )) as {
537
544
  task: string;
@@ -540,6 +547,7 @@ describe("Scheduled Tasks Integration", () => {
540
547
  priority: number;
541
548
  agentId: string;
542
549
  routingReason: string;
550
+ routingSource: string;
543
551
  creatorAgentId: string;
544
552
  };
545
553
 
@@ -548,6 +556,7 @@ describe("Scheduled Tasks Integration", () => {
548
556
  expect(createdTask.priority).toBe(90);
549
557
  expect(createdTask.agentId).toBe(testAgent.id);
550
558
  expect(createdTask.routingReason).toBe("human_pinned");
559
+ expect(createdTask.routingSource).toBe("engine_default");
551
560
  expect(createdTask.creatorAgentId).toBe(testAgent.id);
552
561
 
553
562
  const tags = JSON.parse(createdTask.tags);