@desplega.ai/agent-swarm 1.149.0 → 1.150.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 (385) hide show
  1. package/README.md +7 -3
  2. package/dist/{acp-adapter-4jncb126.js → acp-adapter-d5mzggyk.js} +1 -1
  3. package/dist/{actions-31vp3ae7.js → actions-wn6ew0p7.js} +11 -10
  4. package/dist/{anthropic-messages-vs2rabzp.js → anthropic-messages-ec35ktvx.js} +4 -4
  5. package/dist/{app-1hh67x8w.js → app-dty7p9hg.js} +7 -7
  6. package/dist/{artifact-gj9arwrr.js → artifact-td4q4dch.js} +1 -1
  7. package/dist/{assistant-z66dmz6p.js → assistant-q4vhgjtx.js} +16 -17
  8. package/dist/{boot-reembed-wxa8ya0s.js → boot-reembed-92292pgf.js} +9 -9
  9. package/dist/{boot-reembed-fqzxxzjh.js → boot-reembed-n15q6s9x.js} +8 -8
  10. package/dist/{boot-scrub-logs-jnyndh79.js → boot-scrub-logs-44pc955m.js} +5 -5
  11. package/dist/{claude-adapter-3qpa9w0j.js → claude-adapter-cjegjbje.js} +14 -14
  12. package/dist/{claude-managed-adapter-qvsmh6mv.js → claude-managed-adapter-p3ts5m9m.js} +2 -2
  13. package/dist/{claude-sdk-session-2yxgjs5d.js → claude-sdk-session-7ywbn12v.js} +14 -14
  14. package/dist/{cli-cr12paw2.js → cli-111ey3ra.js} +5 -5
  15. package/dist/{cli-4wtq5jjv.js → cli-1mx65de9.js} +1 -1
  16. package/dist/{cli-9d8ntetj.js → cli-2658f6at.js} +1 -1
  17. package/dist/{cli-n3dz2942.js → cli-3ckzxdt1.js} +10 -6
  18. package/dist/{cli-yb9qhqam.js → cli-3mh119qv.js} +184 -67
  19. package/dist/{cli-ykxrnd1q.js → cli-72xdszyx.js} +2 -2
  20. package/dist/{cli-xm87hzbw.js → cli-7fesa1ky.js} +1 -1
  21. package/dist/{cli-3q5ejx9p.js → cli-7kwmt3r5.js} +2 -2
  22. package/dist/{cli-2qts1hys.js → cli-8chp8xab.js} +2 -2
  23. package/dist/{cli-qaacms9y.js → cli-9gqddmxs.js} +122 -97
  24. package/dist/{cli-zvz62chv.js → cli-a45d5v9b.js} +4 -4
  25. package/dist/{cli-9xvdm3bx.js → cli-asvrh7kj.js} +1 -1
  26. package/dist/{cli-kgz4np97.js → cli-b8x19vbh.js} +4 -4
  27. package/dist/{cli-9fy6nk6g.js → cli-ceb5y160.js} +1 -1
  28. package/dist/{cli-k0cr4kat.js → cli-ck1vqzdj.js} +1 -1
  29. package/dist/{cli-e29gmdmw.js → cli-dv6cdjs2.js} +2 -1
  30. package/dist/{cli-jecc01cb.js → cli-dyx0237s.js} +1 -1
  31. package/dist/{cli-kjwt6hdf.js → cli-gm0fhz13.js} +3 -3
  32. package/dist/{cli-sd5pv3b1.js → cli-h505yhex.js} +2 -2
  33. package/dist/{handlers-nbzdzn9k.js → cli-hbagregr.js} +15 -38
  34. package/dist/{cli-08b07b4r.js → cli-hmyynq9b.js} +1 -1
  35. package/dist/{cli-d8ftsp62.js → cli-kt7wevqh.js} +20 -13
  36. package/dist/{cli-gjhjfeeg.js → cli-kyysm7m3.js} +1 -1
  37. package/dist/{cli-1ebpar1q.js → cli-mzb0n642.js} +6 -6
  38. package/dist/{cli-q50ef8g0.js → cli-n1yj5fd5.js} +1 -1
  39. package/dist/{cli-3apbzgyk.js → cli-n75jt793.js} +13 -9
  40. package/dist/{cli-19f354qr.js → cli-q04q68be.js} +2 -2
  41. package/dist/{cli-yab68w40.js → cli-qp69dd5d.js} +29 -14
  42. package/dist/{cli-6pqcb4q0.js → cli-rnsr8asm.js} +12 -11
  43. package/dist/{cli-ygweqcn4.js → cli-rwp3ksm7.js} +91 -108
  44. package/dist/{cli-phsxnkp6.js → cli-ryz8q8p1.js} +74 -58
  45. package/dist/{cli-e95cx1eb.js → cli-taym3dmg.js} +10 -10
  46. package/dist/{cli-nye12xk5.js → cli-ttje5a4z.js} +7 -4
  47. package/dist/{cli-9hspd3dp.js → cli-vr6qj104.js} +1 -1
  48. package/dist/{cli-mnmsfd1w.js → cli-xjb9wghj.js} +7 -3
  49. package/dist/{cli-gv88e1vf.js → cli-ydk0wjj8.js} +1 -1
  50. package/dist/{cli-aae6hz6a.js → cli-zd21jrrc.js} +3 -3
  51. package/dist/{cli-7smrsr25.js → cli-zthatyrx.js} +23 -11
  52. package/dist/cli.js +19 -19
  53. package/dist/{codex-adapter-8meawydj.js → codex-adapter-rn3aq7jm.js} +7 -7
  54. package/dist/{codex-hook-hfrt9shr.js → codex-hook-gthcmm0g.js} +3 -3
  55. package/dist/{codex-session-runner-gjgxyp5j.js → codex-session-runner-bge0cbsw.js} +7 -7
  56. package/dist/{commands-hz3nb95f.js → commands-26phw0pc.js} +5 -5
  57. package/dist/{db-ggz97zbm.js → db-jxjx6s1b.js} +6 -6
  58. package/dist/{e2b-p04vmtx0.js → e2b-413b8t4v.js} +1 -1
  59. package/dist/handlers-vr1djg4n.js +41 -0
  60. package/dist/{hook-bks2q1f6.js → hook-jw0ztn96.js} +9 -9
  61. package/dist/{hook-kq9wp0ep.js → hook-t6fqsggw.js} +10 -10
  62. package/dist/{http-hrf77v87.js → http-hyc7s57s.js} +80 -71
  63. package/dist/{index-n28pw1zt.js → index-1d9r6a74.js} +18 -18
  64. package/dist/{index-cqtebbhb.js → index-bcyx5djw.js} +17 -17
  65. package/dist/{index-6nsbg88z.js → index-sfhaq59d.js} +408 -74
  66. package/dist/{index-8hmeg8j1.js → index-wtwpthe1.js} +17 -17
  67. package/dist/{keepalive-dxc12gvg.js → keepalive-fbsak4ya.js} +7 -7
  68. package/dist/{lead-yckfn18d.js → lead-rdzdm627.js} +39 -39
  69. package/dist/{maintenance-6kfb2m5e.js → maintenance-25z1c1vf.js} +9 -9
  70. package/dist/{node-x1g4v0pq.js → node-209sxmg3.js} +9 -9
  71. package/dist/{oauth-refresh-sweep-1x1ac722.js → oauth-refresh-sweep-j3d7gtse.js} +6 -6
  72. package/dist/{onboard-dcyt1609.js → onboard-dkcwrc75.js} +2 -2
  73. package/dist/{otel-impl-tbk3e5dr.js → otel-impl-8rgyy3j8.js} +1 -1
  74. package/dist/{pi-mono-adapter-zvshk5cj.js → pi-mono-adapter-4s2bbkgq.js} +8 -8
  75. package/dist/{pricing-refresh-kaqg567e.js → pricing-refresh-9cek71nq.js} +7 -7
  76. package/dist/{rbac-roles-cf97v1vd.js → rbac-roles-vk8mqp9v.js} +6 -6
  77. package/dist/{rbac-roles-ammq6rd2.js → rbac-roles-z98s2ypy.js} +5 -5
  78. package/dist/{render-v2-80w603vy.js → render-v2-3j26g0qh.js} +7 -7
  79. package/dist/{seed-pricing-zbrn83xv.js → seed-pricing-7rxhcnzm.js} +6 -6
  80. package/dist/{setup-fe66kczs.js → setup-e2t7vz0c.js} +2 -2
  81. package/dist/work-objects-8d3nd3x2.js +141 -0
  82. package/dist/{worker-qmb2d1e2.js → worker-0x9fn7nq.js} +39 -39
  83. package/openapi.json +15 -4
  84. package/package.json +3 -3
  85. package/src/agentmail/handlers.ts +5 -0
  86. package/src/be/budget-refusal-notify.ts +1 -0
  87. package/src/be/db/tasks/read.ts +3 -0
  88. package/src/be/db/tasks/write.ts +13 -1
  89. package/src/be/db.ts +4 -2
  90. package/src/be/migrations/153_deferred_task_wait_members.sql +25 -0
  91. package/src/be/migrations/154_routing_source.sql +3 -0
  92. package/src/be/scripts/typecheck.ts +7 -3
  93. package/src/be/seed/automation-toggle.ts +69 -0
  94. package/src/be/seed/schedules-seeder.ts +53 -8
  95. package/src/be/seed/workflows-seeder.ts +35 -6
  96. package/src/be/seed-scripts/catalog/delegate.ts +3 -1
  97. package/src/be/seed-skills/bundled-files.generated.json +1 -1
  98. package/src/be/steering.ts +1 -0
  99. package/src/be/swarm-config-guard.ts +1 -0
  100. package/src/commands/credential-refresh.ts +70 -0
  101. package/src/commands/provider-credentials.ts +2 -25
  102. package/src/commands/runner.ts +23 -56
  103. package/src/github/handlers.ts +9 -0
  104. package/src/gitlab/handlers.ts +4 -0
  105. package/src/heartbeat/heartbeat.ts +3 -0
  106. package/src/http/approval-requests.ts +1 -0
  107. package/src/http/apps.ts +1 -0
  108. package/src/http/config.ts +4 -1
  109. package/src/http/core.ts +4 -2
  110. package/src/http/index.ts +16 -3
  111. package/src/http/script-runs.ts +5 -0
  112. package/src/http/tasks.ts +5 -0
  113. package/src/integrations/kapso/inbound.ts +1 -0
  114. package/src/jira/sync.ts +2 -0
  115. package/src/linear/sync.ts +2 -0
  116. package/src/prompts/session-templates.ts +13 -9
  117. package/src/providers/claude-adapter.ts +21 -8
  118. package/src/scheduler/deferred-task-waits.ts +34 -5
  119. package/src/scheduler/schedule-task.ts +5 -1
  120. package/src/scheduler/scheduler.ts +104 -123
  121. package/src/scripts-runtime/types/stdlib.d.ts +7 -3
  122. package/src/scripts-runtime/types/swarm-sdk.d.ts +7 -3
  123. package/src/slack/HEURISTICS.md +2 -0
  124. package/src/slack/actions.ts +1 -0
  125. package/src/slack/app.ts +2 -0
  126. package/src/slack/assistant.ts +4 -12
  127. package/src/slack/handlers.ts +9 -14
  128. package/src/slack/inbound-files.ts +3 -3
  129. package/src/slack/render-v2.ts +17 -3
  130. package/src/slack/thread-buffer.ts +66 -23
  131. package/src/slack/work-objects.test.ts +252 -0
  132. package/src/slack/work-objects.ts +118 -0
  133. package/src/tasks/worker-follow-up.ts +4 -0
  134. package/src/tests/acp-adapter.test.ts +10 -10
  135. package/src/tests/agent-fs-live-url.test.ts +40 -0
  136. package/src/tests/agent-fs-provision-seeder.test.ts +12 -12
  137. package/src/tests/api-key-tracking.test.ts +18 -18
  138. package/src/tests/api-key.test.ts +4 -2
  139. package/src/tests/apps-rbac.test.ts +1 -1
  140. package/src/tests/apps-spike5.test.ts +1 -1
  141. package/src/tests/apps-sync-engine.test.ts +8 -8
  142. package/src/tests/apps-user-config.test.ts +1 -1
  143. package/src/tests/artifact-sdk.test.ts +8 -8
  144. package/src/tests/asset-key-mcp.test.ts +2 -0
  145. package/src/tests/automation-preflight-alert.test.ts +1 -1
  146. package/src/tests/base-prompt.test.ts +6 -6
  147. package/src/tests/budget-user-scope.test.ts +1 -1
  148. package/src/tests/budgets-routes.test.ts +1 -1
  149. package/src/tests/claude-adapter-binary.test.ts +22 -40
  150. package/src/tests/claude-adapter-otel.test.ts +13 -7
  151. package/src/tests/claude-adapter.test.ts +8 -6
  152. package/src/tests/claude-hook-credentials.test.ts +3 -3
  153. package/src/tests/claude-managed-adapter.test.ts +4 -4
  154. package/src/tests/claude-managed-setup.test.ts +3 -3
  155. package/src/tests/claude-sdk-lifecycle.test.ts +1 -1
  156. package/src/tests/claude-sdk-transport.test.ts +6 -6
  157. package/src/tests/claude-stop-hook.test.ts +8 -8
  158. package/src/tests/claude-worker-parity.test.ts +3 -3
  159. package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +5 -5
  160. package/src/tests/codex-adapter.test.ts +7 -5
  161. package/src/tests/codex-app-server.test.ts +2 -2
  162. package/src/tests/codex-login.test.ts +15 -15
  163. package/src/tests/codex-oauth-credential-info.test.ts +4 -4
  164. package/src/tests/codex-oauth-keep-warm.test.ts +4 -4
  165. package/src/tests/codex-oauth-refresh-lock.test.ts +1 -1
  166. package/src/tests/codex-oauth-storage.test.ts +7 -7
  167. package/src/tests/codex-pool.test.ts +1 -1
  168. package/src/tests/codex-steering-hook.test.ts +1 -1
  169. package/src/tests/codex-swarm-events.test.ts +1 -1
  170. package/src/tests/config-api-only-keys.test.ts +1 -1
  171. package/src/tests/config-session-auth.test.ts +2 -2
  172. package/src/tests/connection-embedded-auth.test.ts +20 -18
  173. package/src/tests/core-auth.test.ts +1 -1
  174. package/src/tests/create-page-tool.test.ts +3 -3
  175. package/src/tests/credential-refresh.test.ts +115 -0
  176. package/src/tests/credential-wait.test.ts +2 -2
  177. package/src/tests/credentials.test.ts +6 -4
  178. package/src/tests/db-queries-oauth.test.ts +40 -40
  179. package/src/tests/defer-task.test.ts +73 -8
  180. package/src/tests/deferred-task-wait-migration.test.ts +64 -0
  181. package/src/tests/deferred-task-wake.test.ts +190 -1
  182. package/src/tests/devin-adapter.test.ts +1 -1
  183. package/src/tests/devin-api.test.ts +1 -1
  184. package/src/tests/e2b-dispatch.test.ts +21 -19
  185. package/src/tests/e2e-claude-transport.test.ts +3 -3
  186. package/src/tests/e2e-redact.test.ts +6 -6
  187. package/src/tests/ensure-token.test.ts +68 -68
  188. package/src/tests/entrypoint-api-readiness.test.ts +1 -1
  189. package/src/tests/entrypoint-codex-oauth-seed.test.ts +13 -13
  190. package/src/tests/events-http.test.ts +1 -1
  191. package/src/tests/fs-routes.test.ts +1 -1
  192. package/src/tests/gitlab-auth.test.ts +10 -10
  193. package/src/tests/harness-provider-resolution.test.ts +8 -5
  194. package/src/tests/heartbeat-reroute-decision.test.ts +1 -0
  195. package/src/tests/helper-credentials.test.ts +137 -0
  196. package/src/tests/http/context-routes.test.ts +2 -2
  197. package/src/tests/http-api-integration.test.ts +5 -2
  198. package/src/tests/http-users.test.ts +1 -1
  199. package/src/tests/identity-refresh.test.ts +2 -2
  200. package/src/tests/internal-ai/complete-structured.test.ts +2 -2
  201. package/src/tests/internal-ai/credentials.test.ts +19 -17
  202. package/src/tests/jira-metadata.test.ts +1 -1
  203. package/src/tests/jira-oauth.test.ts +5 -5
  204. package/src/tests/jira-sync.test.ts +1 -1
  205. package/src/tests/jira-webhook-lifecycle.test.ts +3 -3
  206. package/src/tests/jira-webhook.test.ts +2 -2
  207. package/src/tests/kapso-inbound.test.ts +2 -2
  208. package/src/tests/kv-http.test.ts +1 -1
  209. package/src/tests/kv-namespace-resolution.test.ts +1 -1
  210. package/src/tests/kv-page-proxy.test.ts +2 -2
  211. package/src/tests/launch-password-rejection.test.ts +2 -2
  212. package/src/tests/linear-webhook.test.ts +1 -1
  213. package/src/tests/mcp-oauth-dcr-reuse.test.ts +6 -6
  214. package/src/tests/mcp-oauth-ensure-token.test.ts +28 -22
  215. package/src/tests/mcp-oauth-manual-client.test.ts +16 -12
  216. package/src/tests/mcp-oauth-queries.test.ts +35 -32
  217. package/src/tests/mcp-oauth-resolve-secrets.test.ts +8 -8
  218. package/src/tests/mcp-oauth-wrapper.test.ts +20 -20
  219. package/src/tests/mcp-user-route.test.ts +1 -1
  220. package/src/tests/memory-edges.test.ts +1 -1
  221. package/src/tests/memory-rate-endpoint.test.ts +1 -1
  222. package/src/tests/memory-rate-tool.test.ts +2 -2
  223. package/src/tests/memory-rater-e2e.test.ts +1 -1
  224. package/src/tests/memory-rater-llm-summarizer.test.ts +3 -3
  225. package/src/tests/memory-rater-llm.test.ts +1 -1
  226. package/src/tests/model-control.test.ts +3 -0
  227. package/src/tests/multi-runtime-registration.test.ts +97 -3
  228. package/src/tests/oauth-access-token-tool.test.ts +18 -18
  229. package/src/tests/oauth-callback-flow.test.ts +8 -8
  230. package/src/tests/oauth-credential-bindings.test.ts +29 -27
  231. package/src/tests/oauth-keepalive.test.ts +10 -10
  232. package/src/tests/oauth-presets.test.ts +13 -5
  233. package/src/tests/oauth-refresh-failure.test.ts +9 -9
  234. package/src/tests/oauth-refresh-sweep.test.ts +20 -13
  235. package/src/tests/oauth-wrapper.test.ts +1 -1
  236. package/src/tests/onboard-compose.test.ts +3 -3
  237. package/src/tests/onboard-env.test.ts +26 -26
  238. package/src/tests/onboard-non-interactive.test.ts +4 -4
  239. package/src/tests/opencode-adapter.test.ts +1 -1
  240. package/src/tests/opencode-plugin.test.ts +2 -2
  241. package/src/tests/otel-session-cost-metrics.test.ts +1 -1
  242. package/src/tests/page-proxy-authed.test.ts +2 -2
  243. package/src/tests/page-proxy.test.ts +2 -2
  244. package/src/tests/page-session.test.ts +7 -7
  245. package/src/tests/page-viewer-auth.test.ts +2 -2
  246. package/src/tests/pages-authed-mode.test.ts +1 -1
  247. package/src/tests/pages-http.test.ts +1 -1
  248. package/src/tests/pages-password-mode.test.ts +1 -1
  249. package/src/tests/pages-public-authed-401.test.ts +1 -1
  250. package/src/tests/pages-public-html.test.ts +2 -2
  251. package/src/tests/pages-view-count.test.ts +1 -1
  252. package/src/tests/pi-mono-adapter.test.ts +10 -10
  253. package/src/tests/pi-mono-extension.test.ts +2 -2
  254. package/src/tests/pricing-routes.test.ts +1 -1
  255. package/src/tests/profile-sync-warning.test.ts +8 -8
  256. package/src/tests/profile-sync.test.ts +8 -8
  257. package/src/tests/prompt-template-session.test.ts +36 -5
  258. package/src/tests/provider-process-group.test.ts +95 -4
  259. package/src/tests/providers/pi-cost.test.ts +1 -1
  260. package/src/tests/queue-stall-alarm.test.ts +1 -1
  261. package/src/tests/rbac-admission.test.ts +1 -1
  262. package/src/tests/rbac-charact-http.test.ts +1 -1
  263. package/src/tests/rbac-e2e-helpers.ts +1 -1
  264. package/src/tests/realtime-room-surfaces.test.ts +1 -1
  265. package/src/tests/reload-config.test.ts +1 -1
  266. package/src/tests/routing-reason-contract.test.ts +76 -3
  267. package/src/tests/routing-reason-inventory.test.ts +11 -6
  268. package/src/tests/routing-source.test.ts +53 -0
  269. package/src/tests/runner-agent-fs-provision-retry.test.ts +1 -1
  270. package/src/tests/runner-context-preamble.test.ts +1 -1
  271. package/src/tests/runner-deployment-resume.test.ts +1 -1
  272. package/src/tests/runner-fallback-output.test.ts +1 -1
  273. package/src/tests/runner-identity-refresh.test.ts +1 -1
  274. package/src/tests/runner-skills-refresh.test.ts +1 -1
  275. package/src/tests/schedule-target-type.test.ts +3 -3
  276. package/src/tests/scheduled-tasks.test.ts +14 -5
  277. package/src/tests/scheduler-occurrence.test.ts +347 -0
  278. package/src/tests/script-apis-mcp.test.ts +1 -1
  279. package/src/tests/script-connections-http.test.ts +61 -58
  280. package/src/tests/script-connections-mcp.test.ts +1 -1
  281. package/src/tests/script-connections.test.ts +1 -1
  282. package/src/tests/script-runs-http.test.ts +15 -7
  283. package/src/tests/script-workflows-runtime-e2e.test.ts +1 -1
  284. package/src/tests/scripts-external-api.test.ts +1 -1
  285. package/src/tests/scripts-http.test.ts +1 -1
  286. package/src/tests/scripts-mcp-e2e.test.ts +1 -1
  287. package/src/tests/scripts-only-gating.test.ts +2 -2
  288. package/src/tests/scripts-retention.test.ts +1 -1
  289. package/src/tests/scripts-runtime-identity.test.ts +1 -1
  290. package/src/tests/scripts-runtime-secret-egress.test.ts +1 -1
  291. package/src/tests/scripts-runtime.test.ts +6 -4
  292. package/src/tests/scripts-typecheck.test.ts +21 -0
  293. package/src/tests/sdk-allowlist.test.ts +1 -1
  294. package/src/tests/secret-scrubber.test.ts +38 -31
  295. package/src/tests/seed-registry.test.ts +46 -8
  296. package/src/tests/seed-schedules.test.ts +139 -8
  297. package/src/tests/seed-workflows.test.ts +93 -7
  298. package/src/tests/send-task-output-schema.test.ts +9 -1
  299. package/src/tests/send-task-requested-by.test.ts +1 -0
  300. package/src/tests/send-task-slack-routing-guard.test.ts +2 -0
  301. package/src/tests/session-costs-codex-recompute.test.ts +1 -1
  302. package/src/tests/session-costs-golden.test.ts +2 -2
  303. package/src/tests/session-costs-model-key-normalize.test.ts +2 -2
  304. package/src/tests/session-costs-recompute-all-providers.test.ts +1 -1
  305. package/src/tests/session-tokens.test.ts +1 -1
  306. package/src/tests/shutdown-error-scrubbing.test.ts +1 -1
  307. package/src/tests/slack-file-tools-attachments.test.ts +1 -1
  308. package/src/tests/slack-inbound-files.test.ts +222 -86
  309. package/src/tests/slack-reaction-config.test.ts +5 -4
  310. package/src/tests/slack-read-boundaries.test.ts +1 -1
  311. package/src/tests/slack-render-v2.test.ts +120 -1
  312. package/src/tests/status.test.ts +7 -7
  313. package/src/tests/steering-core.test.ts +1 -1
  314. package/src/tests/steering-transport.test.ts +4 -4
  315. package/src/tests/store-progress-output-guidance.test.ts +34 -0
  316. package/src/tests/swarm-tool-result-gate.test.ts +11 -11
  317. package/src/tests/swarm-x-tool.test.ts +7 -5
  318. package/src/tests/sync-ai-toolbox-skills.test.ts +19 -0
  319. package/src/tests/task-supersede-resume.test.ts +1 -1
  320. package/src/tests/task-tools-ctx.test.ts +2 -0
  321. package/src/tests/tasks-requested-by-filter.test.ts +2 -2
  322. package/src/tests/telemetry-init.test.ts +11 -3
  323. package/src/tests/tool-output-agent-id.test.ts +1 -0
  324. package/src/tests/tracker-fold.test.ts +7 -7
  325. package/src/tests/tracker-tools.test.ts +3 -3
  326. package/src/tests/ui-followup-lead-delegation.test.ts +1 -0
  327. package/src/tests/unified-oauth-migration.test.ts +5 -5
  328. package/src/tests/user-token-rest-auth.test.ts +1 -1
  329. package/src/tests/user-token-routes.test.ts +1 -1
  330. package/src/tests/whoami-route.test.ts +1 -1
  331. package/src/tests/workflow-agent-task.test.ts +15 -13
  332. package/src/tests/workflow-ctx.test.ts +1 -1
  333. package/src/tests/workflow-e2e.test.ts +1 -1
  334. package/src/tests/workflow-engine-v2.test.ts +3 -1
  335. package/src/tests/workflow-executors.test.ts +2 -2
  336. package/src/tests/workflow-http-v2.test.ts +8 -6
  337. package/src/tests/workflow-input-redaction.test.ts +7 -5
  338. package/src/tests/workflow-integration-io.test.ts +2 -2
  339. package/src/tests/workflow-llm.test.ts +5 -5
  340. package/src/tests/workflow-registry.test.ts +1 -1
  341. package/src/tests/workflow-swarm-script.test.ts +1 -1
  342. package/src/tests/workflow-triggers-v2.test.ts +23 -21
  343. package/src/tests/x-composio.test.ts +9 -7
  344. package/src/tests/x402-client.test.ts +1 -1
  345. package/src/tests/x402-config.test.ts +28 -41
  346. package/src/tools/defer-task.ts +156 -24
  347. package/src/tools/send-task.ts +21 -1
  348. package/src/tools/skills/skill-publish.ts +1 -0
  349. package/src/tools/store-progress.ts +1 -1
  350. package/src/tools/templates.ts +2 -1
  351. package/src/types.ts +11 -0
  352. package/src/utils/constants.ts +7 -1
  353. package/src/utils/credentials.test.ts +16 -16
  354. package/src/workflows/executors/agent-task.ts +5 -0
  355. package/templates/ai-toolbox.manifest.json +7 -1
  356. package/templates/schedules/daily-blocker-digest/config.json +6 -1
  357. package/templates/schedules/daily-compounding-reflection/config.json +1 -0
  358. package/templates/schedules/daily-hn-briefing/config.json +1 -1
  359. package/templates/schedules/daily-status-report/config.json +6 -1
  360. package/templates/schedules/daily-swarm-update-check/config.json +19 -0
  361. package/templates/schedules/daily-swarm-update-check/content.md +49 -0
  362. package/templates/schedules/daily-workflow-health-audit/config.json +6 -1
  363. package/templates/schedules/gtm-weekly-review/config.json +1 -1
  364. package/templates/schedules/weekly-code-health-reports/config.json +1 -1
  365. package/templates/schedules/weekly-dependabot-triage/config.json +1 -1
  366. package/templates/schedules/weekly-dora-metrics/config.json +1 -1
  367. package/templates/schedules/weekly-harness-upgrade-check/config.json +1 -1
  368. package/templates/skills/delegate-work/files/scripts/codex-exec.sh +1 -1
  369. package/templates/skills/serply-search/SKILL.md +95 -0
  370. package/templates/skills/serply-search/config.json +13 -0
  371. package/templates/skills/serply-search/content.md +90 -0
  372. package/templates/skills/swarm-scripts/SKILL.md +2 -2
  373. package/templates/skills/swarm-scripts/content.md +2 -2
  374. package/templates/workflows/claude-code-changelog-watch/config.json +1 -1
  375. package/templates/workflows/gsc-topic-miner/config.json +1 -1
  376. package/templates/workflows/linear-drain-loop/config.json +1 -1
  377. package/templates/workflows/llm-safe-release-context/config.json +1 -1
  378. package/templates/workflows/ralph-loop/config.json +1 -1
  379. package/dist/{azure-openai-responses-cqar64rc.js → azure-openai-responses-g85jv7m8.js} +8 -8
  380. package/dist/{cli-4xz3pmrq.js → cli-8qx7jnrk.js} +5 -5
  381. package/dist/{cli-6664w7y4.js → cli-wk0gjrn3.js} +3 -3
  382. package/dist/{google-vertex-ppw8ydpa.js → google-vertex-pkhpkbq9.js} +3 -3
  383. package/dist/{openai-codex-responses-g7w48y30.js → openai-codex-responses-pm5gnyfa.js} +4 -4
  384. package/dist/{openai-completions-0bqmsajw.js → openai-completions-qdcmkfnr.js} +12 -12
  385. package/dist/{openai-responses-nmeyptke.js → openai-responses-vwvk1taj.js} +13 -13
@@ -245,13 +245,13 @@ describe("setup milestones", () => {
245
245
  hint: "Memory search is off. Set OPENAI_API_KEY (or EMBEDDING_API_KEY) on the API server to enable it; it is cheap.",
246
246
  });
247
247
 
248
- process.env.OPENAI_API_KEY = "openai-embedding-key";
248
+ process.env.OPENAI_API_KEY = "example-openai-embedding-key";
249
249
  expect(getMilestone(await buildStatusPayload(), "embeddings").state).toBe("configured");
250
250
 
251
251
  process.env.EMBEDDING_API_KEY = "";
252
252
  expect(getMilestone(await buildStatusPayload(), "embeddings").state).toBe("unverified");
253
253
 
254
- process.env.EMBEDDING_API_KEY = "dedicated-embedding-key";
254
+ process.env.EMBEDDING_API_KEY = "example-dedicated-embedding-key";
255
255
  delete process.env.OPENAI_API_KEY;
256
256
  expect(getMilestone(await buildStatusPayload(), "embeddings").state).toBe("configured");
257
257
  });
@@ -417,7 +417,7 @@ describe("setup milestones", () => {
417
417
  const a = await buildStatusPayload();
418
418
  expect(getMilestone(a, "github").state).toBe("unverified");
419
419
 
420
- process.env.GITHUB_APP_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n...";
420
+ process.env.GITHUB_APP_PRIVATE_KEY = "[REDACTED:github_app_private_key]";
421
421
  const b = await buildStatusPayload();
422
422
  expect(getMilestone(b, "github").state).toBe("verified");
423
423
  });
@@ -456,7 +456,7 @@ describe("setup milestones", () => {
456
456
  scopes: "read",
457
457
  });
458
458
  await storeOAuthTokens("linear", {
459
- accessToken: "lin-tok-xyz",
459
+ accessToken: "example-lin-tok-xyz",
460
460
  refreshToken: "ref",
461
461
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
462
462
  scope: "read",
@@ -475,7 +475,7 @@ describe("setup milestones", () => {
475
475
  // metadata intentionally omitted on first upsert
476
476
  });
477
477
  await storeOAuthTokens("jira", {
478
- accessToken: "jira-tok",
478
+ accessToken: "example-jira-tok",
479
479
  refreshToken: null,
480
480
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
481
481
  scope: null,
@@ -831,7 +831,7 @@ describe("validateProviderCredentials — error scrubbing", () => {
831
831
  });
832
832
 
833
833
  test("devin hits v3/self (not the deprecated v1 endpoint) and passes on 2xx", async () => {
834
- process.env.DEVIN_API_KEY = "cog_fake-devin-key-1234";
834
+ process.env.DEVIN_API_KEY = "example-cog_fake-devin-key-1234";
835
835
  let capturedUrl = "";
836
836
  globalThis.fetch = (async (url) => {
837
837
  capturedUrl = String(url);
@@ -851,7 +851,7 @@ describe("validateProviderCredentials — error scrubbing", () => {
851
851
  });
852
852
 
853
853
  test("scrubs api key from error message on 401 response", async () => {
854
- const fakeKey = "sk-ant-fakekey-DO-NOT-LEAK-1234567890abcdef";
854
+ const fakeKey = "example-anthropic-key-do-not-leak";
855
855
  process.env.ANTHROPIC_API_KEY = fakeKey;
856
856
  globalThis.fetch = (async () =>
857
857
  new Response(`Unauthorized: invalid key ${fakeKey}`, {
@@ -413,7 +413,7 @@ describe("task steering core", () => {
413
413
 
414
414
  test("scrubs secrets before persisting the steering body", async () => {
415
415
  const previous = process.env.OPENAI_API_KEY;
416
- const secret = "sk-proj-steering-secret-value-1234567890";
416
+ const secret = "example-steering-secret-value";
417
417
  process.env.OPENAI_API_KEY = secret;
418
418
  try {
419
419
  const task = await runningTask("pi", "secret scrubbing");
@@ -233,7 +233,7 @@ describe("steering worker transport", () => {
233
233
 
234
234
  test("scrubs provider errors before reporting an undeliverable reason", async () => {
235
235
  const pending = pendingMessage();
236
- const secret = "sk-proj-steering-transport-secret-1234567890";
236
+ const secret = `sk-proj-${"steering".repeat(4)}`;
237
237
  let reportedBody = "";
238
238
  const fetchImpl = (async (input: string | URL | Request, init?: RequestInit) => {
239
239
  if (String(input).includes("/api/steering-messages?")) {
@@ -280,7 +280,7 @@ describe("steering worker transport", () => {
280
280
  expect(requested.outcome).toBe("queued");
281
281
 
282
282
  await pollAndDispatchSteering(
283
- { apiUrl: baseUrl, apiKey: "test-key", agentId: agent.id },
283
+ { apiUrl: baseUrl, apiKey: "example-test-key", agentId: agent.id },
284
284
  task.id,
285
285
  session(),
286
286
  createSteeringDispatchState(),
@@ -327,7 +327,7 @@ describe("steering worker transport", () => {
327
327
  // undeliverable — but the external-delivery flag short-circuits the poll.
328
328
  const codexLikeSession = { ...session(), steeringDeliveredExternally: true };
329
329
  await pollAndDispatchSteering(
330
- { apiUrl: baseUrl, apiKey: "test-key", agentId: agent.id },
330
+ { apiUrl: baseUrl, apiKey: "example-test-key", agentId: agent.id },
331
331
  task.id,
332
332
  codexLikeSession,
333
333
  createSteeringDispatchState(),
@@ -343,7 +343,7 @@ describe("steering worker transport", () => {
343
343
  const previousBaseUrl = process.env.MCP_BASE_URL;
344
344
  const previousApiKey = process.env.AGENT_SWARM_API_KEY;
345
345
  process.env.MCP_BASE_URL = baseUrl;
346
- process.env.AGENT_SWARM_API_KEY = "test-key";
346
+ process.env.AGENT_SWARM_API_KEY = "example-test-key";
347
347
  try {
348
348
  const agent = await createAgent({
349
349
  name: "accept steering worker",
@@ -0,0 +1,34 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import type * as z from "zod";
4
+ import { registerStoreProgressTool } from "../tools/store-progress";
5
+
6
+ describe("store-progress output guidance", () => {
7
+ const server = new McpServer({ name: "output-guidance-test", version: "1.0.0" });
8
+ registerStoreProgressTool(server);
9
+ const tools = (
10
+ server as unknown as {
11
+ _registeredTools: Record<string, { inputSchema: z.ZodObject }>;
12
+ }
13
+ )._registeredTools;
14
+ const outputSchema = tools["store-progress"].inputSchema.shape.output;
15
+
16
+ test("the exposed output field carries the same budget and exceptions as the prompts", () => {
17
+ expect(outputSchema.description).toContain("Keep free-text output under 120 words by default");
18
+ expect(outputSchema.description).toContain("published verbatim in the thread's outcome card");
19
+ expect(outputSchema.description).toContain("every artifact link");
20
+ expect(outputSchema.description).toContain("Link documents instead of inlining them");
21
+ expect(outputSchema.description).toContain(
22
+ "requested depth, enumerated results, essential evidence",
23
+ );
24
+ expect(outputSchema.description).toContain("the task's outputSchema requires longer output");
25
+ expect(outputSchema.description).toContain("output must be JSON matching it");
26
+ });
27
+
28
+ test("the style target does not reject longer requested or schema-constrained output", () => {
29
+ const longResult = "Required result. ".repeat(150);
30
+ for (const output of [longResult, JSON.stringify({ results: [longResult] })]) {
31
+ expect(outputSchema.parse(output)).toBe(output);
32
+ }
33
+ });
34
+ });
@@ -111,38 +111,38 @@ describe("finalizeSwarmToolResult", () => {
111
111
  });
112
112
 
113
113
  test("secrets are scrubbed from message, details, and data at the egress point", async () => {
114
- registerVolatileSecret("sk-super-secret-token-123", "TEST_TOKEN");
114
+ registerVolatileSecret("example-sk-super-secret-token-123", "TEST_TOKEN");
115
115
  try {
116
116
  const result = await finalizeSwarmToolResult("some-tool", {
117
117
  ok: false,
118
- message: "Auth failed with sk-super-secret-token-123",
119
- details: "header was sk-super-secret-token-123",
120
- data: { token: "sk-super-secret-token-123" },
118
+ message: "Auth failed with example-sk-super-secret-token-123",
119
+ details: "header was example-sk-super-secret-token-123",
120
+ data: { token: "example-sk-super-secret-token-123" },
121
121
  });
122
122
  const serialized = JSON.stringify(result);
123
- expect(serialized).not.toContain("sk-super-secret-token-123");
123
+ expect(serialized).not.toContain("example-sk-super-secret-token-123");
124
124
  } finally {
125
125
  clearVolatileSecretsForTesting();
126
126
  }
127
127
  });
128
128
 
129
129
  test("allowSecretEgress skips scrubbing for deliberate credential reveals only", async () => {
130
- registerVolatileSecret("xsk_reveal_me_once_456", "TEST_REVEAL");
130
+ registerVolatileSecret("example-xsk_reveal_me_once_456", "TEST_REVEAL");
131
131
  try {
132
132
  const revealed = await finalizeSwarmToolResult("script-apis", {
133
133
  ok: true,
134
134
  message: "Endpoint created.",
135
- details: "Bearer token (shown once — save it now): xsk_reveal_me_once_456",
136
- data: { token: "xsk_reveal_me_once_456" },
135
+ details: "Bearer token (shown once — save it now): example-xsk_reveal_me_once_456",
136
+ data: { token: "example-xsk_reveal_me_once_456" },
137
137
  allowSecretEgress: true,
138
138
  });
139
- expect(JSON.stringify(revealed)).toContain("xsk_reveal_me_once_456");
139
+ expect(JSON.stringify(revealed)).toContain("example-xsk_reveal_me_once_456");
140
140
 
141
141
  const scrubbed = await finalizeSwarmToolResult("some-tool", {
142
142
  ok: true,
143
- message: "leaky xsk_reveal_me_once_456",
143
+ message: "leaky example-xsk_reveal_me_once_456",
144
144
  });
145
- expect(JSON.stringify(scrubbed)).not.toContain("xsk_reveal_me_once_456");
145
+ expect(JSON.stringify(scrubbed)).not.toContain("example-xsk_reveal_me_once_456");
146
146
  } finally {
147
147
  clearVolatileSecretsForTesting();
148
148
  }
@@ -36,12 +36,14 @@ afterEach(() => {
36
36
 
37
37
  describe("swarm_x MCP tool", () => {
38
38
  test("routes composio requests with server-side auth and scrubbed output", async () => {
39
- process.env.COMPOSIO_API_KEY = "ck_tool_secret_value";
39
+ process.env.COMPOSIO_API_KEY = "example-ck_tool_secret_value";
40
40
  const fetchMock = mock(async (url: string | URL | Request, init?: RequestInit) => {
41
41
  expect(String(url)).toBe("https://backend.composio.dev/api/v3.1/tools?limit=1");
42
42
  expect(init?.method).toBe("GET");
43
- expect((init?.headers as Record<string, string>)["x-api-key"]).toBe("ck_tool_secret_value");
44
- return jsonResponse({ ok: true, token: "ck_tool_secret_value" });
43
+ expect((init?.headers as Record<string, string>)["x-api-key"]).toBe(
44
+ "example-ck_tool_secret_value",
45
+ );
46
+ return jsonResponse({ ok: true, token: "example-ck_tool_secret_value" });
45
47
  });
46
48
  globalThis.fetch = fetchMock;
47
49
 
@@ -65,11 +67,11 @@ describe("swarm_x MCP tool", () => {
65
67
  expect(JSON.stringify(result.structuredContent.response)).toContain(
66
68
  "[REDACTED:COMPOSIO_API_KEY]",
67
69
  );
68
- expect(result.structuredContent.responseText).not.toContain("ck_tool_secret_value");
70
+ expect(result.structuredContent.responseText).not.toContain("example-ck_tool_secret_value");
69
71
  });
70
72
 
71
73
  test("rejects absolute composio paths", async () => {
72
- process.env.COMPOSIO_API_KEY = "ck_tool_secret_value";
74
+ process.env.COMPOSIO_API_KEY = "example-ck_tool_secret_value";
73
75
  const fetchMock = mock(async () => jsonResponse({ ok: true }));
74
76
  globalThis.fetch = fetchMock;
75
77
 
@@ -10,6 +10,7 @@ import {
10
10
  type Manifest,
11
11
  type PathRewrite,
12
12
  parseSkillMd,
13
+ rewriteBundledFileComments,
13
14
  rewriteSkillReferences,
14
15
  sanitizeSyncedVia,
15
16
  stableJson,
@@ -215,6 +216,24 @@ describe("ai-toolbox skill sync pure transforms", () => {
215
216
  ).toThrow("exceed 10485760 bytes total");
216
217
  });
217
218
 
219
+ test("clarifies only the Codex helper comment and preserves executable sandbox settings", () => {
220
+ const comment =
221
+ "# CODEX_SANDBOX default: workspace-write read-only | workspace-write | danger-full-access";
222
+ const executable = `SANDBOX="\${CODEX_SANDBOX:-workspace-write}"\nargs+=( --dangerously-bypass-approvals-and-sandbox )\n`;
223
+ const source = `${comment}\n${executable}`;
224
+ expect(rewriteBundledFileComments("delegate-work", "scripts/codex-exec.sh", source)).toBe(
225
+ `# CODEX_SANDBOX default: workspace-write (passed to codex's -s option)\n${executable}`,
226
+ );
227
+ expect(rewriteBundledFileComments("other", "scripts/codex-exec.sh", source)).toBe(source);
228
+ expect(rewriteBundledFileComments("delegate-work", "scripts/other.sh", source)).toBe(source);
229
+ expect(() =>
230
+ rewriteBundledFileComments("delegate-work", "scripts/codex-exec.sh", executable),
231
+ ).toThrow("expected one upstream sandbox default comment");
232
+ expect(() =>
233
+ rewriteBundledFileComments("delegate-work", "scripts/codex-exec.sh", `${comment}\n${source}`),
234
+ ).toThrow("expected one upstream sandbox default comment");
235
+ });
236
+
218
237
  test("reports executable text downgrades and rejects binary files", () => {
219
238
  const executable = validateBundledFileBytes(
220
239
  "fixture",
@@ -645,7 +645,7 @@ describe("Task Supersede + Resume", () => {
645
645
  test("scrubs secret-shaped values from session-log summaries", async () => {
646
646
  // GitHub PAT-shaped token — matches a structural pattern in
647
647
  // scrubSecrets (regardless of env state).
648
- const fakeToken = "ghp_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
648
+ const fakeToken = `ghp_${"a".repeat(36)}`;
649
649
  mockSessionLogs = [
650
650
  {
651
651
  createdAt: new Date().toISOString(),
@@ -86,6 +86,7 @@ describe("task tool ctx", () => {
86
86
  task: "ordinary direct assignment",
87
87
  agentId: lead.id,
88
88
  routingReason: "skill",
89
+ routingNote: "This test explicitly selects the target worker",
89
90
  offerMode: false,
90
91
  allowDuplicate: false,
91
92
  });
@@ -108,6 +109,7 @@ describe("task tool ctx", () => {
108
109
  task: "ordinary offer",
109
110
  agentId: lead.id,
110
111
  routingReason: "skill",
112
+ routingNote: "This test explicitly selects the target worker",
111
113
  offerMode: true,
112
114
  allowDuplicate: false,
113
115
  });
@@ -101,8 +101,8 @@ describe("getAllTasks / getTasksCount requestedByUserId filter", () => {
101
101
  // `GET /api/tasks` handler actually translates the `?requestedByUserId=none`
102
102
  // sentinel into `requestedByUserIdIsNull`, or that the omitted-param path
103
103
  // stays backwards compatible.
104
- const ROUTE_TEST_DB_PATH = "./test-tasks-requested-by-filter-route.sqlite";
105
- const ROUTE_API_KEY = "test-tasks-requested-by-filter-route";
104
+ const ROUTE_TEST_DB_PATH = "./example-test-tasks-requested-by-filter-route.sqlite";
105
+ const ROUTE_API_KEY = "example-test-tasks-requested-by-filter-route";
106
106
 
107
107
  async function removeDbFiles(path: string): Promise<void> {
108
108
  for (const suffix of ["", "-wal", "-shm"]) {
@@ -204,6 +204,14 @@ describe("initTelemetry", () => {
204
204
  const metadata = (captured as { metadata: Record<string, unknown> }).metadata;
205
205
  expect(metadata.organization_id).toBeUndefined();
206
206
  expect(metadata.organization_name).toBeUndefined();
207
+
208
+ // Dashboard config reloads update the env after telemetry initialized.
209
+ process.env.SWARM_ORG_NAME = " Acme Engineering ";
210
+ track({ event: "test.event", properties: {} });
211
+ await new Promise((r) => setTimeout(r, 0));
212
+ expect((captured as { metadata: Record<string, unknown> }).metadata.organization_name).toBe(
213
+ "Acme Engineering",
214
+ );
207
215
  });
208
216
 
209
217
  test("includes organization_id + organization_name when SWARM_ORG_* set", async () => {
@@ -756,11 +764,11 @@ describe("initTelemetry", () => {
756
764
 
757
765
  describe("_hasEmbeddingKey", () => {
758
766
  test("true when EMBEDDING_API_KEY is set", () => {
759
- expect(_hasEmbeddingKey({ EMBEDDING_API_KEY: "sk-embed" })).toBe(true);
767
+ expect(_hasEmbeddingKey({ EMBEDDING_API_KEY: "example-sk-embed" })).toBe(true);
760
768
  });
761
769
 
762
770
  test("true when OPENAI_API_KEY is set", () => {
763
- expect(_hasEmbeddingKey({ OPENAI_API_KEY: "sk-openai" })).toBe(true);
771
+ expect(_hasEmbeddingKey({ OPENAI_API_KEY: "example-sk-openai" })).toBe(true);
764
772
  });
765
773
 
766
774
  test("false when neither is set (onboard wizard only writes ANTHROPIC_API_KEY)", () => {
@@ -941,7 +949,7 @@ describe("initTelemetry", () => {
941
949
  });
942
950
 
943
951
  test("channels + embedding key all present", async () => {
944
- process.env.EMBEDDING_API_KEY = "sk-embed";
952
+ process.env.EMBEDDING_API_KEY = "example-sk-embed";
945
953
  process.env.SLACK_BOT_TOKEN = "xoxb-1";
946
954
  process.env.SLACK_APP_TOKEN = "xapp-1";
947
955
  process.env.AGENTMAIL_WEBHOOK_SECRET = "whsec_1";
@@ -165,6 +165,7 @@ describe("agent-id fields accept non-UUID agent ids", () => {
165
165
  const parsed = sendTaskInputSchema.parse({
166
166
  agentId: SLUG_WORKER_ID,
167
167
  routingReason: "skill",
168
+ routingNote: "This test explicitly selects the target worker",
168
169
  task: "do the thing",
169
170
  });
170
171
  expect(parsed.agentId).toBe(SLUG_WORKER_ID);
@@ -154,7 +154,7 @@ beforeAll(async () => {
154
154
  expires_in: 3600,
155
155
  scope: "read write",
156
156
  };
157
- if (includeRefreshToken) body.refresh_token = "rotated-refresh-token";
157
+ if (includeRefreshToken) body.refresh_token = "example-rotated-refresh-token";
158
158
  return Response.json(body);
159
159
  }
160
160
  return new Response("not found", { status: 404 });
@@ -227,7 +227,7 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
227
227
  // possible since the carve-out removal made the linear row user-manageable.
228
228
  await upsertOAuthApp("linear", {
229
229
  clientId: "pre-existing",
230
- clientSecret: "pre-existing-secret",
230
+ clientSecret: "example-pre-existing-secret",
231
231
  authorizeUrl: "https://linear.app/oauth/authorize",
232
232
  tokenUrl: "https://api.linear.app/oauth/token",
233
233
  redirectUri: `${appBase}/api/trackers/linear/callback`,
@@ -345,8 +345,8 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
345
345
  const authorization = await upsertAuthorization({
346
346
  appId,
347
347
  label: "default",
348
- accessToken: "stale-access",
349
- refreshToken: "old-refresh",
348
+ accessToken: "example-stale-access",
349
+ refreshToken: "example-old-refresh",
350
350
  expiresAt: new Date(Date.now() - 60_000).toISOString(),
351
351
  status: "active",
352
352
  });
@@ -366,7 +366,7 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
366
366
  body: JSON.stringify({
367
367
  provider: "linear",
368
368
  clientId: "generic-linear-client",
369
- clientSecret: "generic-linear-secret",
369
+ clientSecret: "example-generic-linear-secret",
370
370
  authorizeUrl: "https://linear.app/oauth/authorize",
371
371
  tokenUrl: "https://api.linear.app/oauth/token",
372
372
  scopes: ["read", "write"],
@@ -389,8 +389,8 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
389
389
  const authorization = await upsertAuthorization({
390
390
  appId,
391
391
  label: "default",
392
- accessToken: "initial-access",
393
- refreshToken: "linear-refresh",
392
+ accessToken: "example-initial-access",
393
+ refreshToken: "example-linear-refresh",
394
394
  expiresAt: new Date(Date.now() - 60_000).toISOString(),
395
395
  status: "active",
396
396
  });
@@ -34,7 +34,7 @@ describe("tracker-status (DB layer)", () => {
34
34
  test("returns token info after storing tokens", async () => {
35
35
  await upsertOAuthApp("linear", {
36
36
  clientId: "test-client",
37
- clientSecret: "test-secret",
37
+ clientSecret: "example-test-secret",
38
38
  authorizeUrl: "https://linear.app/oauth/authorize",
39
39
  tokenUrl: "https://api.linear.app/oauth/token",
40
40
  redirectUri: "http://localhost:3013/api/trackers/linear/callback",
@@ -42,8 +42,8 @@ describe("tracker-status (DB layer)", () => {
42
42
  });
43
43
 
44
44
  await storeOAuthTokens("linear", {
45
- accessToken: "test-token",
46
- refreshToken: "test-refresh",
45
+ accessToken: "example-test-token",
46
+ refreshToken: "example-test-refresh",
47
47
  expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(),
48
48
  scope: "read,write",
49
49
  });
@@ -169,6 +169,7 @@ describe("session-UI follow-up → Lead → onward delegation", () => {
169
169
  task: "please pick this up",
170
170
  agentId: differentWorkerId,
171
171
  routingReason: "human_pinned",
172
+ routingNote: "This test explicitly selects the target worker",
172
173
  allowDuplicate: true,
173
174
  },
174
175
  leadAgentId,
@@ -44,7 +44,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
44
44
  id: "app-linear",
45
45
  provider: "linear",
46
46
  clientId: "linear-client",
47
- clientSecret: "linear-client-secret",
47
+ clientSecret: "example-linear-client-secret",
48
48
  authorizeUrl: "https://linear.test/authorize",
49
49
  tokenUrl: "https://linear.test/token",
50
50
  redirectUri: "https://swarm.test/api/oauth/linear/callback",
@@ -60,7 +60,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
60
60
  id: "app-jira",
61
61
  provider: "jira",
62
62
  clientId: "jira-client",
63
- clientSecret: "jira-client-secret",
63
+ clientSecret: "example-jira-client-secret",
64
64
  authorizeUrl: "https://jira.test/authorize",
65
65
  tokenUrl: "https://jira.test/token",
66
66
  redirectUri: "https://swarm.test/api/oauth/jira/callback",
@@ -77,7 +77,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
77
77
  id: "app-vendor",
78
78
  provider: "vendor",
79
79
  clientId: "vendor-client",
80
- clientSecret: "vendor-client-secret",
80
+ clientSecret: "example-vendor-client-secret",
81
81
  authorizeUrl: "https://vendor.test/authorize",
82
82
  tokenUrl: "https://vendor.test/token",
83
83
  redirectUri: "https://swarm.test/api/oauth/vendor/callback",
@@ -422,9 +422,9 @@ describe("migration 117 unified OAuth storage", () => {
422
422
  )
423
423
  .get();
424
424
  expect(encryptedLinear?.clientSecretEncrypted).toBe(1);
425
- expect(encryptedLinear?.clientSecret).not.toBe("linear-client-secret");
425
+ expect(encryptedLinear?.clientSecret).not.toBe("example-linear-client-secret");
426
426
  expect(decryptSecret(encryptedLinear!.clientSecret, getEncryptionKey())).toBe(
427
- "linear-client-secret",
427
+ "example-linear-client-secret",
428
428
  );
429
429
  const encryptedAuthorization = database
430
430
  .query<{ accessToken: string; refreshToken: string | null; tokensEncrypted: number }, []>(
@@ -21,7 +21,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
21
21
  import { listenOnFreePort } from "./test-net";
22
22
 
23
23
  const TEST_DB_PATH = "./test-user-token-rest-auth.sqlite";
24
- const API_KEY = "test-api-key";
24
+ const API_KEY = "example-test-api-key";
25
25
  const ACTOR: IdentityActor = { kind: "operator", id: "op:test" };
26
26
 
27
27
  function createTestServer(): Server {
@@ -14,7 +14,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
14
14
  import { listenOnFreePort } from "./test-net";
15
15
 
16
16
  const TEST_DB_PATH = "./test-user-token-routes.sqlite";
17
- const API_KEY = "test-user-token-key";
17
+ const API_KEY = "example-test-user-token-key";
18
18
  const ORIGINAL_API_KEY = process.env.AGENT_SWARM_API_KEY;
19
19
 
20
20
  async function removeDbFiles(path: string): Promise<void> {
@@ -24,7 +24,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
24
24
  import { listenOnFreePort } from "./test-net";
25
25
 
26
26
  const TEST_DB_PATH = "./test-whoami-route.sqlite";
27
- const API_KEY = "test-api-key";
27
+ const API_KEY = "example-test-api-key";
28
28
  const ACTOR: IdentityActor = { kind: "operator", id: "op:test" };
29
29
 
30
30
  interface WhoamiBody {
@@ -37,7 +37,6 @@ const mockDeps: ExecutorDependencies = {
37
37
  // IDs for workflow prerequisites (set in beforeAll)
38
38
  let workflowId: string;
39
39
  let runId: string;
40
- let stepId1: string;
41
40
  let stepId2: string;
42
41
 
43
42
  // ─── Setup / Teardown ────────────────────────────────────────
@@ -64,14 +63,6 @@ beforeAll(async () => {
64
63
  const run = await createWorkflowRun({ id: crypto.randomUUID(), workflowId: wf.id });
65
64
  runId = run.id;
66
65
 
67
- const step1 = await createWorkflowRunStep({
68
- id: crypto.randomUUID(),
69
- runId: run.id,
70
- nodeId: "test-node-1",
71
- nodeType: "agent-task",
72
- });
73
- stepId1 = step1.id;
74
-
75
66
  const step2 = await createWorkflowRunStep({
76
67
  id: crypto.randomUUID(),
77
68
  runId: run.id,
@@ -159,7 +150,10 @@ describe("AgentTaskExecutor — workspace scoping", () => {
159
150
  expect(parsed.success).toBe(false);
160
151
  });
161
152
 
162
- test("execute() creates task with workspace fields forwarded", async () => {
153
+ test.each([
154
+ undefined,
155
+ "skill",
156
+ ] as const)("execute() forwards workspace fields and routing provenance for %s", async (routingReason) => {
163
157
  const executor = new AgentTaskExecutor(mockDeps);
164
158
  const worker = await createAgent({
165
159
  name: "Pinned workflow worker",
@@ -168,15 +162,22 @@ describe("AgentTaskExecutor — workspace scoping", () => {
168
162
  });
169
163
  const config = {
170
164
  agentId: worker.id,
165
+ routingReason,
171
166
  template: "List files in workspace",
172
167
  dir: "/workspace/repos/agent-swarm",
173
168
  vcsRepo: "desplega-ai/agent-swarm",
174
169
  model: "sonnet",
175
170
  };
171
+ const step = await createWorkflowRunStep({
172
+ id: crypto.randomUUID(),
173
+ runId,
174
+ nodeId: `routing-${routingReason ?? "default"}`,
175
+ nodeType: "agent-task",
176
+ });
176
177
  const meta: ExecutorMeta = {
177
178
  runId,
178
- stepId: stepId1,
179
- nodeId: "test-node-1",
179
+ stepId: step.id,
180
+ nodeId: step.nodeId,
180
181
  workflowId,
181
182
  dryRun: false,
182
183
  };
@@ -195,7 +196,8 @@ describe("AgentTaskExecutor — workspace scoping", () => {
195
196
  expect(task!.modelTier).toBe("regular");
196
197
  expect(task!.source).toBe("workflow");
197
198
  expect(task!.agentId).toBe(worker.id);
198
- expect(task!.routingReason).toBe("human_pinned");
199
+ expect(task!.routingReason).toBe(routingReason ?? "human_pinned");
200
+ expect(task!.routingSource).toBe(routingReason ? "declared" : "engine_default");
199
201
  });
200
202
 
201
203
  test("execute() creates task without workspace fields (backward compat)", async () => {
@@ -19,7 +19,7 @@ describe("workflow-ctx: ctx.swarm proxy tool name resolution", () => {
19
19
  const { ctx } = buildWorkflowCtx({
20
20
  runId: "test-run",
21
21
  agentId: "test-agent",
22
- apiKey: "test-key",
22
+ apiKey: "example-test-key",
23
23
  baseUrl: "http://localhost:9999",
24
24
  args: {},
25
25
  });
@@ -26,7 +26,7 @@ import { SKIP_SANDBOX_SPAWN_TESTS } from "./sandbox-spawn-test-helpers";
26
26
  const spawnDescribe = describe.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
27
27
 
28
28
  const TEST_DB_PATH = "./test-workflow-e2e.sqlite";
29
- const API_KEY = "test-workflow-e2e-key-1234567890";
29
+ const API_KEY = "example-test-workflow-e2e-key-1234567890";
30
30
 
31
31
  const noOpEmbeddingProvider = {
32
32
  name: "test/noop-workflow-e2e-embedding",
@@ -43,6 +43,8 @@ const skip = test.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
43
43
 
44
44
  const TEST_DB_PATH = "./test-workflow-engine-v2.sqlite";
45
45
 
46
+ const inputRef = (name: string): string => `input.${name}`;
47
+
46
48
  // ─── Test Executors ──────────────────────────────────────────
47
49
 
48
50
  class EchoExecutor extends BaseExecutor<typeof EchoExecutor.schema, typeof EchoExecutor.outSchema> {
@@ -1158,7 +1160,7 @@ describe("interpolateNodeConfig — script node", () => {
1158
1160
  test("an inputs alias pointing at workflow input is still interpolated into the script", () => {
1159
1161
  const node = {
1160
1162
  type: "script",
1161
- inputs: { token: "input.API_TOKEN" },
1163
+ inputs: { token: inputRef("API_TOKEN") },
1162
1164
  config: { runtime: "bash", script: "curl -H 'Authorization: {{token}}' https://x" },
1163
1165
  };
1164
1166
  const ctx = { input: { API_TOKEN: "tok-123" }, token: "tok-123" };
@@ -594,8 +594,8 @@ describe("ScriptExecutor", () => {
594
594
 
595
595
  skip("child process never inherits the server's secrets — env is scrubbed, not passed through", async () => {
596
596
  const savedKey = process.env.AGENT_SWARM_API_KEY;
597
- process.env.AGENT_SWARM_API_KEY = "super-secret-operator-bearer";
598
- process.env.SOME_OTHER_SERVER_SECRET = "also-should-not-leak";
597
+ process.env.AGENT_SWARM_API_KEY = "example-super-secret-operator-bearer";
598
+ process.env.SOME_OTHER_SERVER_SECRET = "example-also-should-not-leak";
599
599
  try {
600
600
  const result = await executor.run(
601
601
  input(