@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
@@ -53,8 +53,8 @@ function makeServer(name: string) {
53
53
 
54
54
  const base = (mcpServerId: string) => ({
55
55
  mcpServerId,
56
- accessToken: "access-123",
57
- refreshToken: "refresh-456",
56
+ accessToken: "example-access-123",
57
+ refreshToken: "example-refresh-456",
58
58
  tokenType: "Bearer",
59
59
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
60
60
  scope: "read write",
@@ -64,7 +64,7 @@ const base = (mcpServerId: string) => ({
64
64
  tokenUrl: "https://as.example.com/token",
65
65
  revocationUrl: null,
66
66
  dcrClientId: "client-abc",
67
- dcrClientSecret: "dcr-secret-xyz",
67
+ dcrClientSecret: "example-dcr-secret-xyz",
68
68
  clientSource: "dcr" as const,
69
69
  status: "connected" as const,
70
70
  });
@@ -76,9 +76,9 @@ describe("mcp_oauth_tokens encryption roundtrip", () => {
76
76
  const token = await getMcpOAuthToken(server.id);
77
77
 
78
78
  expect(token).not.toBeNull();
79
- expect(token!.accessToken).toBe("access-123");
80
- expect(token!.refreshToken).toBe("refresh-456");
81
- expect(token!.dcrClientSecret).toBe("dcr-secret-xyz");
79
+ expect(token!.accessToken).toBe("example-access-123");
80
+ expect(token!.refreshToken).toBe("example-refresh-456");
81
+ expect(token!.dcrClientSecret).toBe("example-dcr-secret-xyz");
82
82
  expect(token!.tokenVersion).toBe(1);
83
83
  expect(token!.status).toBe("connected");
84
84
  const app = await getDbClient().get<{ source: string; metadata: string }>(
@@ -91,7 +91,10 @@ describe("mcp_oauth_tokens encryption roundtrip", () => {
91
91
 
92
92
  test("access token is encrypted at rest (not stored plaintext)", async () => {
93
93
  const server = await makeServer("mcp-enc-at-rest");
94
- await upsertMcpOAuthToken({ ...base(server.id), accessToken: "UNIQUE_PLAINTEXT_TOKEN_ABC" });
94
+ await upsertMcpOAuthToken({
95
+ ...base(server.id),
96
+ accessToken: "example-UNIQUE_PLAINTEXT_TOKEN_ABC",
97
+ });
95
98
 
96
99
  // Use raw SQL to inspect the row bypassing the decrypt helper.
97
100
  const row = (await getDbClient().get(
@@ -105,7 +108,7 @@ describe("mcp_oauth_tokens encryption roundtrip", () => {
105
108
  )) as { accessToken: string } | null;
106
109
 
107
110
  expect(row).not.toBeNull();
108
- expect(row!.accessToken).not.toBe("UNIQUE_PLAINTEXT_TOKEN_ABC");
111
+ expect(row!.accessToken).not.toBe("example-UNIQUE_PLAINTEXT_TOKEN_ABC");
109
112
  expect(row!.accessToken.length).toBeGreaterThan(24);
110
113
  });
111
114
 
@@ -114,15 +117,15 @@ describe("mcp_oauth_tokens encryption roundtrip", () => {
114
117
  await upsertMcpOAuthToken(base(server.id));
115
118
  await upsertMcpOAuthToken({
116
119
  ...base(server.id),
117
- accessToken: "access-updated",
120
+ accessToken: "example-access-updated",
118
121
  refreshToken: undefined,
119
122
  scope: "read",
120
123
  });
121
124
  const token = await getMcpOAuthToken(server.id);
122
- expect(token!.accessToken).toBe("access-updated");
125
+ expect(token!.accessToken).toBe("example-access-updated");
123
126
  // COALESCE behaviour on refreshToken: not overridden when updater omits it
124
127
  // (we re-pass the same refresh above, so expect it intact).
125
- expect(token!.refreshToken).toBe("refresh-456");
128
+ expect(token!.refreshToken).toBe("example-refresh-456");
126
129
  });
127
130
 
128
131
  test("refresh CAS uses the tokenVersion observed before the provider request", async () => {
@@ -132,20 +135,20 @@ describe("mcp_oauth_tokens encryption roundtrip", () => {
132
135
 
133
136
  await upsertMcpOAuthToken({
134
137
  ...base(server.id),
135
- accessToken: "concurrent-winner",
136
- refreshToken: "refresh-456",
138
+ accessToken: "example-concurrent-winner",
139
+ refreshToken: "example-refresh-456",
137
140
  });
138
141
 
139
142
  await expect(
140
143
  applyMcpOAuthRefresh(observed.id, {
141
- accessToken: "stale-refresh-result",
142
- refreshToken: "stale-refresh-token",
144
+ accessToken: "example-stale-refresh-result",
145
+ refreshToken: "example-stale-refresh-token",
143
146
  expectedTokenVersion: observed.tokenVersion,
144
147
  }),
145
148
  ).rejects.toThrow(/token version changed during refresh/);
146
149
  expect(await getMcpOAuthToken(server.id)).toMatchObject({
147
- accessToken: "concurrent-winner",
148
- refreshToken: "refresh-456",
150
+ accessToken: "example-concurrent-winner",
151
+ refreshToken: "example-refresh-456",
149
152
  });
150
153
  });
151
154
  });
@@ -178,13 +181,13 @@ describe("markMcpOAuthTokenStatus + deleteMcpOAuthToken", () => {
178
181
 
179
182
  await upsertMcpOAuthToken({
180
183
  ...base(server.id),
181
- accessToken: "reconnected-access",
182
- refreshToken: "reconnected-refresh",
184
+ accessToken: "example-reconnected-access",
185
+ refreshToken: "example-reconnected-refresh",
183
186
  });
184
187
  expect(await getMcpOAuthToken(server.id)).toMatchObject({
185
188
  id: original.id,
186
- accessToken: "reconnected-access",
187
- refreshToken: "reconnected-refresh",
189
+ accessToken: "example-reconnected-access",
190
+ refreshToken: "example-reconnected-refresh",
188
191
  status: "connected",
189
192
  });
190
193
  });
@@ -264,13 +267,13 @@ describe("mcp_oauth_pending (state PK)", () => {
264
267
  tokenUrl: "https://as.example.com/token",
265
268
  redirectUri: "https://swarm.example.com/cb",
266
269
  dcrClientId: "client-abc",
267
- dcrClientSecret: "secret-xyz",
270
+ dcrClientSecret: "example-secret-xyz",
268
271
  });
269
272
 
270
273
  const consumed = await consumeMcpOAuthPending("state-1");
271
274
  expect(consumed).not.toBeNull();
272
275
  expect(consumed!.codeVerifier).toBe("verifier-plain-1");
273
- expect(consumed!.dcrClientSecret).toBe("secret-xyz");
276
+ expect(consumed!.dcrClientSecret).toBe("example-secret-xyz");
274
277
  expect(consumed!.mcpServerId).toBe(server.id);
275
278
 
276
279
  // Second consume returns null (row deleted).
@@ -297,7 +300,7 @@ describe("mcp_oauth_pending (state PK)", () => {
297
300
  authorizeUrl: `https://issuer-${suffix}.example.com/authorize`,
298
301
  tokenUrl: `https://issuer-${suffix}.example.com/token`,
299
302
  dcrClientId: `client-${suffix}`,
300
- dcrClientSecret: `secret-${suffix}`,
303
+ dcrClientSecret: `example-secret-${suffix}`,
301
304
  redirectUri: "https://swarm.example.com/cb",
302
305
  });
303
306
  }
@@ -306,13 +309,13 @@ describe("mcp_oauth_pending (state PK)", () => {
306
309
  resourceUrl: "https://resource-b.example.com",
307
310
  tokenUrl: "https://issuer-b.example.com/token",
308
311
  dcrClientId: "client-b",
309
- dcrClientSecret: "secret-b",
312
+ dcrClientSecret: "example-secret-b",
310
313
  });
311
314
  expect(await consumeMcpOAuthPending("state-a")).toMatchObject({
312
315
  resourceUrl: "https://resource-a.example.com",
313
316
  tokenUrl: "https://issuer-a.example.com/token",
314
317
  dcrClientId: "client-a",
315
- dcrClientSecret: "secret-a",
318
+ dcrClientSecret: "example-secret-a",
316
319
  });
317
320
  });
318
321
 
@@ -328,7 +331,7 @@ describe("mcp_oauth_pending (state PK)", () => {
328
331
  authorizeUrl: "https://replacement-issuer.example.com/authorize",
329
332
  tokenUrl: "https://replacement-issuer.example.com/token",
330
333
  dcrClientId: "replacement-client",
331
- dcrClientSecret: "replacement-secret",
334
+ dcrClientSecret: "example-replacement-secret",
332
335
  redirectUri: "https://swarm.example.com/cb",
333
336
  });
334
337
 
@@ -394,7 +397,7 @@ describe("findReusableMcpOAuthClient / invalidateMcpOAuthClient", () => {
394
397
  const reusable = await findReusableMcpOAuthClient(server.id);
395
398
  expect(reusable).toMatchObject({
396
399
  clientId: "client-abc",
397
- clientSecret: "dcr-secret-xyz",
400
+ clientSecret: "example-dcr-secret-xyz",
398
401
  authorizationServerIssuer: "https://issuer.example.com",
399
402
  registrationEndpoint: "https://issuer.example.com/register",
400
403
  clientSource: "dcr",
@@ -431,7 +434,7 @@ describe("findReusableMcpOAuthClient / invalidateMcpOAuthClient", () => {
431
434
  authorizeUrl: "https://issuer.example.com/authorize",
432
435
  tokenUrl: "https://issuer.example.com/token",
433
436
  dcrClientId: "pending-client",
434
- dcrClientSecret: "pending-secret",
437
+ dcrClientSecret: "example-pending-secret",
435
438
  redirectUri: "https://swarm.example.com/cb",
436
439
  });
437
440
 
@@ -440,7 +443,7 @@ describe("findReusableMcpOAuthClient / invalidateMcpOAuthClient", () => {
440
443
  const reusable = await findReusableMcpOAuthClient(server.id);
441
444
  expect(reusable).toMatchObject({
442
445
  clientId: "pending-client",
443
- clientSecret: "pending-secret",
446
+ clientSecret: "example-pending-secret",
444
447
  authorizationServerIssuer: "https://issuer.example.com",
445
448
  registrationEndpoint: "https://issuer.example.com/register",
446
449
  });
@@ -463,7 +466,7 @@ describe("findReusableMcpOAuthClient / invalidateMcpOAuthClient", () => {
463
466
  authorizeUrl: "https://issuer.example.com/authorize",
464
467
  tokenUrl: "https://issuer.example.com/token",
465
468
  dcrClientId: "pending-client",
466
- dcrClientSecret: "pending-secret",
469
+ dcrClientSecret: "example-pending-secret",
467
470
  redirectUri: "https://swarm.example.com/cb",
468
471
  });
469
472
  const after = (
@@ -491,7 +494,7 @@ describe("findReusableMcpOAuthClient / invalidateMcpOAuthClient", () => {
491
494
 
492
495
  // A fresh legitimate write (e.g. re-registering after invalidation)
493
496
  // clears the flag again.
494
- await upsertMcpOAuthToken({ ...base(server.id), accessToken: "fresh-access" });
497
+ await upsertMcpOAuthToken({ ...base(server.id), accessToken: "example-fresh-access" });
495
498
  expect(await findReusableMcpOAuthClient(server.id)).not.toBeNull();
496
499
  });
497
500
 
@@ -81,7 +81,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
81
81
  await setMcpServerAuthMethod(mcp.id, "oauth");
82
82
  await upsertMcpOAuthToken({
83
83
  mcpServerId: mcp.id,
84
- accessToken: "bearer-live-123",
84
+ accessToken: "example-bearer-live-123",
85
85
  refreshToken: null,
86
86
  expiresAt: new Date(Date.now() + 3600_000).toISOString(), // fresh, no refresh path
87
87
  resourceUrl: "https://mcp.example.com/",
@@ -96,7 +96,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
96
96
  const match = result.servers.find((s) => s.id === mcp.id);
97
97
  expect(match).toBeTruthy();
98
98
  expect(match!.authMethod).toBe("oauth");
99
- expect(match!.resolvedHeaders?.Authorization).toBe("Bearer bearer-live-123");
99
+ expect(match!.resolvedHeaders?.Authorization).toBe("Bearer example-bearer-live-123");
100
100
  expect(match!.authError).toBeNull();
101
101
  });
102
102
 
@@ -122,7 +122,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
122
122
  await setMcpServerAuthMethod(mcp.id, "oauth");
123
123
  await upsertMcpOAuthToken({
124
124
  mcpServerId: mcp.id,
125
- accessToken: "lowercase-token-xyz",
125
+ accessToken: "example-lowercase-token-xyz",
126
126
  refreshToken: null,
127
127
  tokenType: "bearer", // lowercase, as RFC 6749 prescribes
128
128
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
@@ -137,7 +137,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
137
137
  const result = await agentMcpServers(agent.id);
138
138
  const match = result.servers.find((s) => s.id === mcp.id);
139
139
  expect(match).toBeTruthy();
140
- expect(match!.resolvedHeaders?.Authorization).toBe("Bearer lowercase-token-xyz");
140
+ expect(match!.resolvedHeaders?.Authorization).toBe("Bearer example-lowercase-token-xyz");
141
141
  expect(match!.resolvedHeaders?.Authorization?.startsWith("Bearer ")).toBe(true);
142
142
  });
143
143
 
@@ -161,7 +161,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
161
161
  await setMcpServerAuthMethod(mcp.id, "oauth");
162
162
  await upsertMcpOAuthToken({
163
163
  mcpServerId: mcp.id,
164
- accessToken: "mac-token-xyz",
164
+ accessToken: "example-mac-token-xyz",
165
165
  refreshToken: null,
166
166
  tokenType: "MAC",
167
167
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
@@ -176,7 +176,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
176
176
  const result = await agentMcpServers(agent.id);
177
177
  const match = result.servers.find((s) => s.id === mcp.id);
178
178
  expect(match).toBeTruthy();
179
- expect(match!.resolvedHeaders?.Authorization).toBe("MAC mac-token-xyz");
179
+ expect(match!.resolvedHeaders?.Authorization).toBe("MAC example-mac-token-xyz");
180
180
  });
181
181
 
182
182
  test("OAuth server without token row surfaces authError", async () => {
@@ -261,7 +261,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
261
261
  await setMcpServerAuthMethod(mcp.id, "oauth");
262
262
  await upsertMcpOAuthToken({
263
263
  mcpServerId: mcp.id,
264
- accessToken: "new-bearer",
264
+ accessToken: "example-new-bearer",
265
265
  refreshToken: null,
266
266
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
267
267
  resourceUrl: "https://mcp.example.com/",
@@ -274,7 +274,7 @@ describe("resolveSecrets integration — OAuth Authorization injection", () => {
274
274
 
275
275
  const result = await agentMcpServers(agent.id);
276
276
  const match = result.servers.find((s) => s.id === mcp.id);
277
- expect(match!.resolvedHeaders?.Authorization).toBe("Bearer new-bearer");
277
+ expect(match!.resolvedHeaders?.Authorization).toBe("Bearer example-new-bearer");
278
278
  });
279
279
 
280
280
  test("static server retains default authError=null in the response shape", async () => {
@@ -389,7 +389,7 @@ describe("registerClient (RFC 7591 DCR)", () => {
389
389
  return new Response(
390
390
  JSON.stringify({
391
391
  client_id: "issued-id",
392
- client_secret: "issued-secret",
392
+ client_secret: "example-issued-secret",
393
393
  client_id_issued_at: 1700000000,
394
394
  }),
395
395
  { status: 201, headers: { "Content-Type": "application/json" } },
@@ -404,7 +404,7 @@ describe("registerClient (RFC 7591 DCR)", () => {
404
404
  });
405
405
 
406
406
  expect(res.client_id).toBe("issued-id");
407
- expect(res.client_secret).toBe("issued-secret");
407
+ expect(res.client_secret).toBe("example-issued-secret");
408
408
  expect(capturedBody).toBeTruthy();
409
409
  expect(JSON.parse(capturedBody!).client_name).toBe("agent-swarm");
410
410
  });
@@ -471,7 +471,7 @@ describe("exchangeCodeForTokens", () => {
471
471
  const res = await exchangeCodeForTokens({
472
472
  tokenUrl: "https://as.example.com/token",
473
473
  clientId: "client-xyz",
474
- clientSecret: "secret-xyz",
474
+ clientSecret: "example-secret-xyz",
475
475
  tokenEndpointAuthMethod: "client_secret_post",
476
476
  redirectUri: "https://swarm.example.com/callback",
477
477
  code: "authcode-1",
@@ -485,7 +485,7 @@ describe("exchangeCodeForTokens", () => {
485
485
  expect(params.get("code")).toBe("authcode-1");
486
486
  expect(params.get("code_verifier")).toBe("verifier-1");
487
487
  expect(params.get("resource")).toBe("https://mcp.example.com/");
488
- expect(params.get("client_secret")).toBe("secret-xyz");
488
+ expect(params.get("client_secret")).toBe("example-secret-xyz");
489
489
  expect(res.access_token).toBe("at-1");
490
490
  });
491
491
 
@@ -551,8 +551,8 @@ describe("refreshMcpToken", () => {
551
551
  });
552
552
 
553
553
  test("scrubs an echoed client_secret/refresh_token from the thrown error body", async () => {
554
- const clientSecret = "super-secret-client-value-123456";
555
- const refreshToken = "super-secret-refresh-value-654321";
554
+ const clientSecret = "example-super-secret-client-value-123456";
555
+ const refreshToken = "example-super-secret-refresh-value-654321";
556
556
  globalThis.fetch = async () =>
557
557
  new Response(
558
558
  JSON.stringify({
@@ -706,7 +706,7 @@ describe("token-endpoint client authentication is applied per the registered met
706
706
  await exchangeCodeForTokens({
707
707
  tokenUrl: "https://as.example.com/token",
708
708
  clientId: creds.clientId ?? "client-xyz",
709
- clientSecret: creds.clientSecret ?? "secret-xyz",
709
+ clientSecret: creds.clientSecret ?? "example-secret-xyz",
710
710
  tokenEndpointAuthMethod,
711
711
  redirectUri: "https://swarm.example.com/callback",
712
712
  code: "authcode-1",
@@ -719,7 +719,7 @@ describe("token-endpoint client authentication is applied per the registered met
719
719
  test("client_secret_basic → Authorization: Basic header, no creds in the body", async () => {
720
720
  const { params, headers } = await captureExchange("client_secret_basic");
721
721
  expect(headers.Authorization).toBe(
722
- `Basic ${Buffer.from("client-xyz:secret-xyz").toString("base64")}`,
722
+ `Basic ${Buffer.from("client-xyz:example-secret-xyz").toString("base64")}`,
723
723
  );
724
724
  expect(params.get("client_id")).toBeNull();
725
725
  expect(params.get("client_secret")).toBeNull();
@@ -729,7 +729,7 @@ describe("token-endpoint client authentication is applied per the registered met
729
729
  const { params, headers } = await captureExchange("client_secret_post");
730
730
  expect(headers.Authorization).toBeUndefined();
731
731
  expect(params.get("client_id")).toBe("client-xyz");
732
- expect(params.get("client_secret")).toBe("secret-xyz");
732
+ expect(params.get("client_secret")).toBe("example-secret-xyz");
733
733
  });
734
734
 
735
735
  test("none → client_id only in the body, no secret anywhere", async () => {
@@ -821,7 +821,7 @@ describe("token-endpoint client authentication is applied per the registered met
821
821
  await exchangeCodeForTokens({
822
822
  tokenUrl: "https://as.example.com/token",
823
823
  clientId: "client-xyz",
824
- clientSecret: "secret-xyz",
824
+ clientSecret: "example-secret-xyz",
825
825
  tokenEndpointAuthMethod: "client_secret_post",
826
826
  redirectUri: "https://swarm.example.com/callback",
827
827
  code,
@@ -836,7 +836,7 @@ describe("token-endpoint client authentication is applied per the registered met
836
836
  });
837
837
 
838
838
  test("a form-encoded refresh token is redacted on a failed refresh", async () => {
839
- const refreshToken = "rt+slash/eq=";
839
+ const refreshToken = "example-rt+slash/eq=";
840
840
  const encoded = new URLSearchParams({ v: refreshToken }).toString().slice(2);
841
841
  globalThis.fetch = async () =>
842
842
  new Response(`{"detail":"refresh_token=${encoded}"}`, { status: 400 });
@@ -844,7 +844,7 @@ describe("token-endpoint client authentication is applied per the registered met
844
844
  await refreshMcpToken({
845
845
  tokenUrl: "https://as.example.com/token",
846
846
  clientId: "client-xyz",
847
- clientSecret: "secret-xyz",
847
+ clientSecret: "example-secret-xyz",
848
848
  tokenEndpointAuthMethod: "client_secret_post",
849
849
  refreshToken,
850
850
  resource: "https://mcp.example.com/",
@@ -856,7 +856,7 @@ describe("token-endpoint client authentication is applied per the registered met
856
856
  });
857
857
 
858
858
  test("a form-encoded revoked token is redacted on a failed revocation", async () => {
859
- const token = "tok+slash/eq=";
859
+ const token = "example-tok+slash/eq=";
860
860
  const encoded = new URLSearchParams({ v: token }).toString().slice(2);
861
861
  globalThis.fetch = async () => new Response(`{"detail":"token=${encoded}"}`, { status: 400 });
862
862
 
@@ -864,7 +864,7 @@ describe("token-endpoint client authentication is applied per the registered met
864
864
  revocationUrl: "https://as.example.com/revoke",
865
865
  token,
866
866
  clientId: "client-xyz",
867
- clientSecret: "secret-xyz",
867
+ clientSecret: "example-secret-xyz",
868
868
  tokenEndpointAuthMethod: "client_secret_post",
869
869
  }).catch((err: Error) => {
870
870
  expect(err.message).toContain("Token revocation failed (400)");
@@ -876,7 +876,7 @@ describe("token-endpoint client authentication is applied per the registered met
876
876
  test("an upstream error body echoing the client secret is scrubbed before it is thrown", async () => {
877
877
  // The callback logs this message AND reflects it into the dashboard
878
878
  // redirect as error_description, so an echoed credential would escape.
879
- const secret = "sk-echoed-secret-value-1234567890";
879
+ const secret = "example-echoed-client-secret-value";
880
880
  globalThis.fetch = async () =>
881
881
  new Response(`{"error":"invalid_client","detail":"bad client_secret: ${secret}"}`, {
882
882
  status: 401,
@@ -910,14 +910,14 @@ describe("token-endpoint client authentication is applied per the registered met
910
910
  });
911
911
 
912
912
  test("a revocation error body echoing the token is scrubbed before it is thrown", async () => {
913
- const token = "rt-echoed-refresh-token-0987654321";
913
+ const token = "example-rt-echoed-refresh-token-0987654321";
914
914
  globalThis.fetch = async () => new Response(`{"error":"bad token: ${token}"}`, { status: 400 });
915
915
 
916
916
  await revokeMcpToken({
917
917
  revocationUrl: "https://as.example.com/revoke",
918
918
  token,
919
919
  clientId: "client-xyz",
920
- clientSecret: "secret-xyz",
920
+ clientSecret: "example-secret-xyz",
921
921
  tokenEndpointAuthMethod: "client_secret_post",
922
922
  }).catch((err: Error) => {
923
923
  expect(err.message).toContain("Token revocation failed (400)");
@@ -929,7 +929,7 @@ describe("token-endpoint client authentication is applied per the registered met
929
929
  for (const missing of [undefined, null, "some-unknown-method"]) {
930
930
  const { params, headers } = await captureExchange(missing);
931
931
  expect(headers.Authorization).toBe(
932
- `Basic ${Buffer.from("client-xyz:secret-xyz").toString("base64")}`,
932
+ `Basic ${Buffer.from("client-xyz:example-secret-xyz").toString("base64")}`,
933
933
  );
934
934
  expect(params.get("client_id")).toBeNull();
935
935
  expect(params.get("client_secret")).toBeNull();
@@ -980,7 +980,7 @@ describe("token-endpoint client authentication is applied per the registered met
980
980
  await refreshMcpToken({
981
981
  tokenUrl: "https://as.example.com/token",
982
982
  clientId: "client-xyz",
983
- clientSecret: "secret-xyz",
983
+ clientSecret: "example-secret-xyz",
984
984
  tokenEndpointAuthMethod: "client_secret_basic",
985
985
  refreshToken: "rt-abc",
986
986
  resource: "https://mcp.example.com/",
@@ -988,7 +988,7 @@ describe("token-endpoint client authentication is applied per the registered met
988
988
 
989
989
  const params = new URLSearchParams(capturedBody);
990
990
  expect(capturedHeaders.Authorization).toBe(
991
- `Basic ${Buffer.from("client-xyz:secret-xyz").toString("base64")}`,
991
+ `Basic ${Buffer.from("client-xyz:example-secret-xyz").toString("base64")}`,
992
992
  );
993
993
  expect(params.get("client_id")).toBeNull();
994
994
  expect(params.get("client_secret")).toBeNull();
@@ -23,7 +23,7 @@ import { handleMcpUser } from "../http/mcp-user";
23
23
  import { listenOnFreePort } from "./test-net";
24
24
 
25
25
  const TEST_DB_PATH = "./test-mcp-user-route.sqlite";
26
- const API_KEY = "test-mcp-user-key";
26
+ const API_KEY = "example-test-mcp-user-key";
27
27
  const ACTOR: IdentityActor = { kind: "operator", id: "test" };
28
28
 
29
29
  async function removeDbFiles(path: string): Promise<void> {
@@ -32,7 +32,7 @@ import { getFreePort, SERVER_BOOT_HOOK_TIMEOUT_MS, waitForServer } from "./test-
32
32
  let TEST_PORT = 0;
33
33
  const TEST_DB_PATH = `/tmp/test-memory-edges-${Date.now()}.sqlite`;
34
34
  let BASE = "";
35
- const API_KEY = "test-key";
35
+ const API_KEY = "example-test-key";
36
36
 
37
37
  let serverProc: Subprocess;
38
38
  const agentA = randomUUID();
@@ -293,3 +293,35 @@ test("boot re-embedding still updates rows belonging to multiple agents", async
293
293
  });
294
294
  }
295
295
  });
296
+
297
+ // Regression: memories written while no embedding key was configured have
298
+ // embedding = NULL, not a wrong-dimension value. The backfill used to only
299
+ // target `embedding IS NOT NULL AND length != N`, so these rows were never
300
+ // swept once a key landed — the customer-reported symptom (60 memories with
301
+ // 0 embeddings, permanently stuck on FTS/keyword fallback).
302
+ test("boot re-embedding backfills rows that never got an embedding at all", async () => {
303
+ const memory = await store.store({
304
+ agentId: owner,
305
+ scope: "agent",
306
+ name: randomUUID(),
307
+ content: "never embedded",
308
+ source: "manual",
309
+ });
310
+ const before = await getDbClient().get<{ embedding: unknown }>(
311
+ "SELECT embedding FROM agent_memory WHERE id = ?",
312
+ [memory.id],
313
+ );
314
+ expect(before?.embedding).toBeNull();
315
+
316
+ await runBootReembed();
317
+
318
+ const row = await getDbClient().get(
319
+ "SELECT agentId, length(embedding) AS bytes, embeddingModel FROM agent_memory WHERE id = ?",
320
+ [memory.id],
321
+ );
322
+ expect(row).toEqual({
323
+ agentId: memory.agentId,
324
+ bytes: EMBEDDING_DIMENSIONS * 4,
325
+ embeddingModel: provider.name,
326
+ });
327
+ });
@@ -20,7 +20,7 @@ import { getFreePort, SERVER_BOOT_HOOK_TIMEOUT_MS, waitForServer } from "./test-
20
20
  let TEST_PORT = 0;
21
21
  const TEST_DB_PATH = `/tmp/test-memory-rate-${Date.now()}.sqlite`;
22
22
  let BASE = "";
23
- const API_KEY = "test-key";
23
+ const API_KEY = "example-test-key";
24
24
 
25
25
  let serverProc: Subprocess;
26
26
  const agentA = randomUUID();
@@ -64,7 +64,7 @@ const memoryId = "22222222-2222-4222-8222-222222222222";
64
64
  describe("memory_rate MCP tool", () => {
65
65
  beforeEach(() => {
66
66
  process.env.MCP_BASE_URL = "http://test-host:9999";
67
- process.env.API_KEY = "test-key";
67
+ process.env.API_KEY = "example-test-key";
68
68
  });
69
69
 
70
70
  afterEach(() => {
@@ -89,7 +89,7 @@ describe("memory_rate MCP tool", () => {
89
89
  expect(calls[0]!.init?.method).toBe("POST");
90
90
  const headers = calls[0]!.init?.headers as Record<string, string>;
91
91
  expect(headers["X-Agent-ID"]).toBe("agent-abc");
92
- expect(headers.Authorization).toBe("Bearer test-key");
92
+ expect(headers.Authorization).toBe("Bearer example-test-key");
93
93
  const body = JSON.parse(calls[0]!.init?.body as string);
94
94
  expect(body).toEqual({
95
95
  events: [
@@ -49,7 +49,7 @@ import { getFreePort, SERVER_BOOT_HOOK_TIMEOUT_MS, waitForServer } from "./test-
49
49
  let TEST_PORT = 0;
50
50
  const TEST_DB_PATH = `/tmp/test-memory-rater-e2e-${Date.now()}.sqlite`;
51
51
  let BASE = "";
52
- const API_KEY = "test-key";
52
+ const API_KEY = "example-test-key";
53
53
 
54
54
  let serverProc: Subprocess;
55
55
  let store: SqliteMemoryStore;
@@ -113,7 +113,7 @@ describe("runMemoryRater — request shape", () => {
113
113
 
114
114
  const result = await runMemoryRater({
115
115
  prompt: "test prompt",
116
- apiKey: "test-api-key-123",
116
+ apiKey: "example-test-api-key-123",
117
117
  fetchImpl: fakeFetch,
118
118
  });
119
119
 
@@ -125,7 +125,7 @@ describe("runMemoryRater — request shape", () => {
125
125
 
126
126
  const headers = capturedInit?.headers as Record<string, string>;
127
127
  expect(headers["Content-Type"]).toBe("application/json");
128
- expect(headers.Authorization).toBe("Bearer test-api-key-123");
128
+ expect(headers.Authorization).toBe("Bearer example-test-api-key-123");
129
129
 
130
130
  const body = JSON.parse(String(capturedInit?.body));
131
131
  expect(body.model).toBe(DEFAULT_MEMORY_RATER_MODEL);
@@ -151,7 +151,7 @@ describe("runMemoryRater — request shape", () => {
151
151
 
152
152
  const result = await runMemoryRater({
153
153
  prompt: "test prompt",
154
- apiKey: "test-api-key-123",
154
+ apiKey: "example-test-api-key-123",
155
155
  fetchImpl: fakeFetch,
156
156
  });
157
157
 
@@ -520,7 +520,7 @@ describe("LlmRater.rate(ctx) — per-memory path with MockLlmRaterClient", () =>
520
520
  let TEST_PORT = 0;
521
521
  const TEST_DB_PATH = `/tmp/test-memory-rater-llm-${Date.now()}.sqlite`;
522
522
  let BASE = "";
523
- const API_KEY = "test-key";
523
+ const API_KEY = "example-test-key";
524
524
 
525
525
  let serverProc: Subprocess;
526
526
  const agentA = randomUUID();
@@ -560,6 +560,7 @@ describe("Model Control - Zod Validation Schema", () => {
560
560
  sendTaskInputSchema.parse({
561
561
  agentId: crypto.randomUUID(),
562
562
  routingReason: "human_pinned",
563
+ routingNote: "This test explicitly selects the target worker",
563
564
  task: "x",
564
565
  model: "gpt-5.5",
565
566
  }).model,
@@ -583,6 +584,7 @@ describe("Model Control - Zod Validation Schema", () => {
583
584
  sendTaskInputSchema.parse({
584
585
  agentId: crypto.randomUUID(),
585
586
  routingReason: "human_pinned",
587
+ routingNote: "This test explicitly selects the target worker",
586
588
  task: "x",
587
589
  effort: "xhigh",
588
590
  }).effort,
@@ -591,6 +593,7 @@ describe("Model Control - Zod Validation Schema", () => {
591
593
  sendTaskInputSchema.parse({
592
594
  agentId: crypto.randomUUID(),
593
595
  routingReason: "human_pinned",
596
+ routingNote: "This test explicitly selects the target worker",
594
597
  task: "x",
595
598
  effort: "max",
596
599
  }).effort,
@@ -89,11 +89,11 @@ afterAll(async () => {
89
89
  });
90
90
 
91
91
  describe("MULTI_RUNTIME_ENABLED on the authenticated stats endpoint", () => {
92
- test("reports false when the flag is unset — multi-runtime is opt-in", async () => {
92
+ test("reports true when the flag is unset", async () => {
93
93
  await withMultiRuntime(undefined, async () => {
94
94
  const stats = await api("GET", "/api/stats");
95
95
  expect(stats.status).toBe(200);
96
- expect(stats.body.multiRuntimeEnabled).toBe(false);
96
+ expect(stats.body.multiRuntimeEnabled).toBe(true);
97
97
  });
98
98
  });
99
99