@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
@@ -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();
@@ -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,
@@ -3,7 +3,7 @@
3
3
  * handlers on both sides of MULTI_RUNTIME_ENABLED.
4
4
  */
5
5
 
6
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
6
+ import { afterAll, beforeAll, beforeEach, describe, expect, spyOn, test } from "bun:test";
7
7
  import { unlink } from "node:fs/promises";
8
8
  import { createServer as createHttpServer, type Server } from "node:http";
9
9
  import {
@@ -15,6 +15,7 @@ import {
15
15
  getActiveTaskCount,
16
16
  getAgentById,
17
17
  getDbClient,
18
+ getIdleWorkersWithCapacity,
18
19
  getSwarmConfigs,
19
20
  getTaskById,
20
21
  hasCapacity,
@@ -22,6 +23,7 @@ import {
22
23
  releaseStaleOfferedTasksForOfflineAgents,
23
24
  startTask,
24
25
  updateAgentStatus,
26
+ updateAgentStatusFromCapacity,
25
27
  upsertSwarmConfig,
26
28
  } from "../be/db";
27
29
  import {
@@ -32,8 +34,16 @@ import {
32
34
  getRuntimeInstanceById,
33
35
  hasReadyLiveRuntime,
34
36
  } from "../be/multi-runtime";
37
+ import {
38
+ CREDENTIAL_RETRY_INTERVAL_MS,
39
+ type CredentialRefreshState,
40
+ refreshCredentialStatus,
41
+ } from "../commands/credential-refresh";
35
42
  import { retryBootStep } from "../commands/credential-wait";
36
- import { sendCredStatusReport } from "../commands/provider-credentials";
43
+ import {
44
+ CREDENTIAL_PROVIDER_CHECKERS,
45
+ sendCredStatusReport,
46
+ } from "../commands/provider-credentials";
37
47
  import { runHeartbeatSweep } from "../heartbeat/heartbeat";
38
48
  import { handleActiveSessions } from "../http/active-sessions";
39
49
  import { handleAgentRegister, handleAgentsRest } from "../http/agents";
@@ -49,7 +59,7 @@ import { listenOnFreePort } from "./test-net";
49
59
 
50
60
  const TEST_DB_PATH = "./test-multi-runtime-registration.sqlite";
51
61
  let baseUrl = "";
52
- const API_KEY = "test-multi-runtime-key";
62
+ const API_KEY = "example-test-multi-runtime-key";
53
63
 
54
64
  const LEAD_ID = "44444444-4444-4444-4444-444444444444";
55
65
 
@@ -2840,3 +2850,87 @@ describe("MCP task-action accept requires a live runtime", () => {
2840
2850
  expect((await getTaskById(task.id))?.agentId).toBe(id);
2841
2851
  });
2842
2852
  });
2853
+
2854
+ describe("post-task credential recovery without a restart", () => {
2855
+ for (const multiRuntime of [false, true]) {
2856
+ test(`parked worker recovers with multi-runtime ${multiRuntime ? "on" : "off"}`, async () => {
2857
+ process.env.MULTI_RUNTIME_ENABLED = String(multiRuntime);
2858
+ const id = await makeAgent(1);
2859
+ const runtimeInstanceId = crypto.randomUUID();
2860
+ await register(id, { maxTasks: 1, runtimeInstanceId });
2861
+ const api = { apiUrl: baseUrl, apiKey: API_KEY, agentId: id, runtimeInstanceId };
2862
+ const refresh: CredentialRefreshState = {
2863
+ harnessProvider: "acp",
2864
+ ready: true,
2865
+ lastRefreshAt: 0,
2866
+ inFlight: false,
2867
+ };
2868
+ const check = spyOn(CREDENTIAL_PROVIDER_CHECKERS, "claude");
2869
+ const originalOAuth = process.env.CLAUDE_CODE_OAUTH_TOKEN;
2870
+ // The real Claude checker and live-test use OAuth presence, no upstream I/O.
2871
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "test-credential-recovery";
2872
+ try {
2873
+ // A live provider swap produces a real not-ready post-task snapshot.
2874
+ await refreshCredentialStatus(api, refresh, "claude", {}, 1);
2875
+ expect((await getAgentById(id))?.status).toBe("waiting_for_credentials");
2876
+ expect((await getAgentById(id))?.credStatus?.reportKind).toBe("post_task");
2877
+ expect((await getIdleWorkersWithCapacity()).some((agent) => agent.id === id)).toBe(false);
2878
+ if (multiRuntime) {
2879
+ expect((await getRuntimeInstanceById(runtimeInstanceId))?.credentialReady).toBe(false);
2880
+ }
2881
+
2882
+ // Ping and completion/capacity reconciliation cannot recover it.
2883
+ await pingAgent(id, runtimeInstanceId);
2884
+ await updateAgentStatusFromCapacity(id);
2885
+ expect((await getAgentById(id))?.status).toBe("waiting_for_credentials");
2886
+ await refreshCredentialStatus(api, refresh, "claude", {}, CREDENTIAL_RETRY_INTERVAL_MS);
2887
+ expect(check).toHaveBeenCalledTimes(1);
2888
+
2889
+ // A still-missing snapshot stays parked, and starts a new throttle window.
2890
+ await refreshCredentialStatus(api, refresh, "claude", {}, CREDENTIAL_RETRY_INTERVAL_MS + 1);
2891
+ expect(check).toHaveBeenCalledTimes(2);
2892
+ expect((await getAgentById(id))?.status).toBe("waiting_for_credentials");
2893
+ const env = { CLAUDE_CODE_OAUTH_TOKEN: "test-credential-recovery" };
2894
+ await refreshCredentialStatus(
2895
+ api,
2896
+ refresh,
2897
+ "claude",
2898
+ env,
2899
+ 2 * CREDENTIAL_RETRY_INTERVAL_MS,
2900
+ );
2901
+ expect(check).toHaveBeenCalledTimes(2);
2902
+ expect((await getAgentById(id))?.status).toBe("waiting_for_credentials");
2903
+
2904
+ // Credentials resolve. Same runner state, provider, and runtime identity.
2905
+ await refreshCredentialStatus(
2906
+ api,
2907
+ refresh,
2908
+ "claude",
2909
+ env,
2910
+ 2 * CREDENTIAL_RETRY_INTERVAL_MS + 1,
2911
+ );
2912
+ expect(check).toHaveBeenCalledTimes(3);
2913
+ expect((await getAgentById(id))?.status).toBe("idle");
2914
+ expect((await getAgentById(id))?.credStatus?.ready).toBe(true);
2915
+ expect((await getAgentById(id))?.credentialMissing).toBeNull();
2916
+ expect((await getIdleWorkersWithCapacity()).some((agent) => agent.id === id)).toBe(true);
2917
+ if (multiRuntime) {
2918
+ expect((await getRuntimeInstanceById(runtimeInstanceId))?.credentialReady).toBe(true);
2919
+ expect(await countActiveRuntimeInstancesForAgent(id)).toBe(1);
2920
+ }
2921
+ await refreshCredentialStatus(
2922
+ api,
2923
+ refresh,
2924
+ "claude",
2925
+ env,
2926
+ 10 * CREDENTIAL_RETRY_INTERVAL_MS,
2927
+ );
2928
+ expect(check).toHaveBeenCalledTimes(3);
2929
+ } finally {
2930
+ check.mockRestore();
2931
+ if (originalOAuth === undefined) delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
2932
+ else process.env.CLAUDE_CODE_OAUTH_TOKEN = originalOAuth;
2933
+ }
2934
+ });
2935
+ }
2936
+ });
@@ -23,7 +23,7 @@ const originalFetch = globalThis.fetch;
23
23
 
24
24
  const testApp = {
25
25
  clientId: "client-id",
26
- clientSecret: "client-secret",
26
+ clientSecret: "example-client-secret",
27
27
  authorizeUrl: "https://example.com/oauth/authorize",
28
28
  tokenUrl: "https://example.com/oauth/token",
29
29
  redirectUri: "http://localhost:3013/callback",
@@ -69,8 +69,8 @@ afterAll(async () => {
69
69
  describe("resolveOAuthAccessToken", () => {
70
70
  test("registered MCP tool returns a seeded provider token", async () => {
71
71
  await storeOAuthTokens("custom-provider", {
72
- accessToken: "mcp-tool-access-token-plain-value",
73
- refreshToken: "mcp-tool-refresh-token",
72
+ accessToken: "example-mcp-tool-access-token-plain-value",
73
+ refreshToken: "example-mcp-tool-refresh-token",
74
74
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
75
75
  });
76
76
  const server = new McpServer({ name: "oauth-access-token-test", version: "1.0.0" });
@@ -112,7 +112,7 @@ describe("resolveOAuthAccessToken", () => {
112
112
  expect(result.structuredContent).toMatchObject({
113
113
  success: true,
114
114
  provider: "custom-provider",
115
- accessToken: "mcp-tool-access-token-plain-value",
115
+ accessToken: "example-mcp-tool-access-token-plain-value",
116
116
  expiresAt: expect.any(String),
117
117
  tokenType: "Bearer",
118
118
  });
@@ -123,7 +123,7 @@ describe("resolveOAuthAccessToken", () => {
123
123
  // details carries the actual token payload (allowSecretEgress: true means
124
124
  // the central scrubber does not redact it, since the tool's whole purpose
125
125
  // is handing over the plaintext token).
126
- expect(result.structuredContent.details).toBe("mcp-tool-access-token-plain-value");
126
+ expect(result.structuredContent.details).toBe("example-mcp-tool-access-token-plain-value");
127
127
 
128
128
  // content[0].text is composed as message + "\n\n" + details, so both
129
129
  // channels (text for pi/opencode/claude-managed, structuredContent for
@@ -132,7 +132,7 @@ describe("resolveOAuthAccessToken", () => {
132
132
  expect(result.content).toHaveLength(1);
133
133
  expect(result.content[0].type).toBe("text");
134
134
  expect(result.content[0].text).toBe(
135
- `custom-provider OAuth access token resolved; expires at ${expiresAt}.\n\nmcp-tool-access-token-plain-value`,
135
+ `custom-provider OAuth access token resolved; expires at ${expiresAt}.\n\nexample-mcp-tool-access-token-plain-value`,
136
136
  );
137
137
  });
138
138
 
@@ -170,10 +170,10 @@ describe("resolveOAuthAccessToken", () => {
170
170
  });
171
171
 
172
172
  test("returns a fresh access token and registers it for scrubber redaction", async () => {
173
- const accessToken = "linear-access-token-plain-value-1234567890";
173
+ const accessToken = "example-linear-access-token-plain-value-1234567890";
174
174
  await storeOAuthTokens("linear", {
175
175
  accessToken,
176
- refreshToken: "linear-refresh-token",
176
+ refreshToken: "example-linear-refresh-token",
177
177
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
178
178
  });
179
179
 
@@ -192,21 +192,21 @@ describe("resolveOAuthAccessToken", () => {
192
192
 
193
193
  test("supports any configured OAuth provider slug", async () => {
194
194
  await storeOAuthTokens("custom-provider", {
195
- accessToken: "custom-provider-access-token-plain-value",
196
- refreshToken: "custom-provider-refresh-token",
195
+ accessToken: "example-custom-provider-access-token-plain-value",
196
+ refreshToken: "example-custom-provider-refresh-token",
197
197
  expiresAt: new Date(Date.now() + 3600_000).toISOString(),
198
198
  });
199
199
 
200
200
  const result = await resolveOAuthAccessToken("custom-provider");
201
201
 
202
202
  expect(result.provider).toBe("custom-provider");
203
- expect(result.accessToken).toBe("custom-provider-access-token-plain-value");
203
+ expect(result.accessToken).toBe("example-custom-provider-access-token-plain-value");
204
204
  });
205
205
 
206
206
  test("refreshes Jira before returning a near-expiry token", async () => {
207
207
  await storeOAuthTokens("jira", {
208
- accessToken: "old-jira-access-token",
209
- refreshToken: "old-jira-refresh-token",
208
+ accessToken: "example-old-jira-access-token",
209
+ refreshToken: "example-old-jira-refresh-token",
210
210
  expiresAt: new Date(Date.now() + 60_000).toISOString(),
211
211
  });
212
212
 
@@ -214,10 +214,10 @@ describe("resolveOAuthAccessToken", () => {
214
214
  Promise.resolve(
215
215
  new Response(
216
216
  JSON.stringify({
217
- access_token: "new-jira-access-token-plain-value",
217
+ access_token: "example-new-jira-access-token-plain-value",
218
218
  token_type: "Bearer",
219
219
  expires_in: 3600,
220
- refresh_token: "new-jira-refresh-token",
220
+ refresh_token: "example-new-jira-refresh-token",
221
221
  }),
222
222
  { status: 200, headers: { "Content-Type": "application/json" } },
223
223
  ),
@@ -228,13 +228,13 @@ describe("resolveOAuthAccessToken", () => {
228
228
  const result = await resolveOAuthAccessToken("jira");
229
229
 
230
230
  expect(fetchSpy).toHaveBeenCalledTimes(1);
231
- expect(result.accessToken).toBe("new-jira-access-token-plain-value");
232
- expect((await getOAuthTokens("jira"))?.refreshToken).toBe("new-jira-refresh-token");
231
+ expect(result.accessToken).toBe("example-new-jira-access-token-plain-value");
232
+ expect((await getOAuthTokens("jira"))?.refreshToken).toBe("example-new-jira-refresh-token");
233
233
  });
234
234
 
235
235
  test("rejects a near-expiry token when no refresh token is available", async () => {
236
236
  await storeOAuthTokens("jira", {
237
- accessToken: "stale-jira-access-token",
237
+ accessToken: "example-stale-jira-access-token",
238
238
  refreshToken: null,
239
239
  expiresAt: new Date(Date.now() + 60_000).toISOString(),
240
240
  });
@@ -85,10 +85,10 @@ beforeAll(async () => {
85
85
  if (url.pathname === "/token") {
86
86
  lastTokenBody = await req.text();
87
87
  return Response.json({
88
- access_token: "mock-access-token",
88
+ access_token: "example-mock-access-token",
89
89
  token_type: "Bearer",
90
90
  expires_in: 3600,
91
- refresh_token: "mock-refresh-token",
91
+ refresh_token: "example-mock-refresh-token",
92
92
  scope: "read write",
93
93
  });
94
94
  }
@@ -98,7 +98,7 @@ beforeAll(async () => {
98
98
  // fabricated one.
99
99
  lastTokenBody = await req.text();
100
100
  return Response.json({
101
- access_token: "mock-access-token",
101
+ access_token: "example-mock-access-token",
102
102
  token_type: "bearer",
103
103
  scope: "read",
104
104
  });
@@ -183,8 +183,8 @@ describe("static OAuth callback + multi-authorization flow", () => {
183
183
  expect(supportAuth.accountEmail).toBe("connected@example.test");
184
184
  // Tokens are encrypted at rest but decrypt to the mock values on read.
185
185
  expect(supportAuth.tokensEncrypted).toBe(true);
186
- expect(supportAuth.accessToken).toBe("mock-access-token");
187
- expect(supportAuth.refreshToken).toBe("mock-refresh-token");
186
+ expect(supportAuth.accessToken).toBe("example-mock-access-token");
187
+ expect(supportAuth.refreshToken).toBe("example-mock-refresh-token");
188
188
 
189
189
  // Second label: "sales" — first authorization must be untouched.
190
190
  const sales = await buildAuthorizationUrl(config, { appId, label: "sales", flow: "generic" });
@@ -383,7 +383,7 @@ describe("static OAuth callback + multi-authorization flow", () => {
383
383
  tokenUrl: `${providerBase}/token`,
384
384
  scopes: "read",
385
385
  dcrClientId: "mcp-client",
386
- dcrClientSecret: "mcp-secret",
386
+ dcrClientSecret: "example-mcp-secret",
387
387
  redirectUri: `${appBase}/api/oauth/callback`,
388
388
  });
389
389
 
@@ -464,7 +464,7 @@ describe("step-4 security hardening", () => {
464
464
  try {
465
465
  const identity = await captureIdentity({
466
466
  userinfoUrl: "http://127.0.0.1/userinfo",
467
- accessToken: "live-bearer",
467
+ accessToken: "example-live-bearer",
468
468
  });
469
469
  expect(identity).toBeNull();
470
470
  } finally {
@@ -476,7 +476,7 @@ describe("step-4 security hardening", () => {
476
476
  test("captureIdentity does not follow a redirect to a private host", async () => {
477
477
  const identity = await captureIdentity({
478
478
  userinfoUrl: `${providerBase}/userinfo-redirect`,
479
- accessToken: "live-bearer",
479
+ accessToken: "example-live-bearer",
480
480
  });
481
481
  // The 302 is not followed (redirect: manual → not .ok), so no identity.
482
482
  expect(identity).toBeNull();
@@ -144,7 +144,7 @@ describe("OAuth credential bindings", () => {
144
144
 
145
145
  await upsertOAuthApp("phase2-roundtrip", testApp("phase2-roundtrip"));
146
146
  await storeOAuthTokens("phase2-roundtrip", {
147
- accessToken: "roundtrip-access",
147
+ accessToken: "example-roundtrip-access",
148
148
  expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
149
149
  });
150
150
  const authorizationId = (await getOAuthTokens("phase2-roundtrip"))!.id;
@@ -170,8 +170,8 @@ describe("OAuth credential bindings", () => {
170
170
  test("OAuth binding resolves through the stored access token", async () => {
171
171
  await upsertOAuthApp("phase2-resolve", testApp("phase2-resolve"));
172
172
  await storeOAuthTokens("phase2-resolve", {
173
- accessToken: "stored-oauth-access",
174
- refreshToken: "stored-oauth-refresh",
173
+ accessToken: "example-stored-oauth-access",
174
+ refreshToken: "example-stored-oauth-refresh",
175
175
  expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
176
176
  });
177
177
  await upsertCredentialBinding({
@@ -188,7 +188,7 @@ describe("OAuth credential bindings", () => {
188
188
  expect(bindings).toContainEqual(
189
189
  expect.objectContaining({
190
190
  configKey: "PHASE2_RESOLVE_OAUTH",
191
- value: "stored-oauth-access",
191
+ value: "example-stored-oauth-access",
192
192
  }),
193
193
  );
194
194
  });
@@ -196,8 +196,8 @@ describe("OAuth credential bindings", () => {
196
196
  test("expiring OAuth binding token is refreshed before resolution", async () => {
197
197
  await upsertOAuthApp("phase2-refresh", testApp("phase2-refresh"));
198
198
  await storeOAuthTokens("phase2-refresh", {
199
- accessToken: "old-access-token",
200
- refreshToken: "old-refresh-token",
199
+ accessToken: "example-old-access-token",
200
+ refreshToken: "example-old-refresh-token",
201
201
  expiresAt: new Date(Date.now() + 60 * 1000).toISOString(),
202
202
  });
203
203
  await upsertCredentialBinding({
@@ -215,13 +215,13 @@ describe("OAuth credential bindings", () => {
215
215
  }
216
216
  expect(init?.method).toBe("POST");
217
217
  expect(String(init?.body)).toContain("grant_type=refresh_token");
218
- expect(String(init?.body)).toContain("refresh_token=old-refresh-token");
218
+ expect(String(init?.body)).toContain("refresh_token=example-old-refresh-token");
219
219
  return Promise.resolve(
220
220
  Response.json({
221
- access_token: "new-access-token",
221
+ access_token: "example-new-access-token",
222
222
  token_type: "Bearer",
223
223
  expires_in: 3600,
224
- refresh_token: "new-refresh-token",
224
+ refresh_token: "example-new-refresh-token",
225
225
  }),
226
226
  );
227
227
  });
@@ -233,10 +233,12 @@ describe("OAuth credential bindings", () => {
233
233
  expect(bindings).toContainEqual(
234
234
  expect.objectContaining({
235
235
  configKey: "PHASE2_REFRESH_OAUTH",
236
- value: "new-access-token",
236
+ value: "example-new-access-token",
237
237
  }),
238
238
  );
239
- expect((await getOAuthTokens("phase2-refresh"))?.refreshToken).toBe("new-refresh-token");
239
+ expect((await getOAuthTokens("phase2-refresh"))?.refreshToken).toBe(
240
+ "example-new-refresh-token",
241
+ );
240
242
  });
241
243
 
242
244
  test("basic tokenAuthStyle + json tokenBodyFormat reach the token endpoint (Notion-style)", async () => {
@@ -245,8 +247,8 @@ describe("OAuth credential bindings", () => {
245
247
  metadata: JSON.stringify({ tokenAuthStyle: "basic", tokenBodyFormat: "json" }),
246
248
  });
247
249
  await storeOAuthTokens("phase2-basic", {
248
- accessToken: "old-basic-access",
249
- refreshToken: "old-basic-refresh",
250
+ accessToken: "example-old-basic-access",
251
+ refreshToken: "example-old-basic-refresh",
250
252
  expiresAt: new Date(Date.now() + 60 * 1000).toISOString(),
251
253
  });
252
254
  await upsertCredentialBinding({
@@ -272,16 +274,16 @@ describe("OAuth credential bindings", () => {
272
274
  expect(headers.get("content-type")).toBe("application/json");
273
275
  const body = JSON.parse(String(init?.body)) as Record<string, string>;
274
276
  expect(body.grant_type).toBe("refresh_token");
275
- expect(body.refresh_token).toBe("old-basic-refresh");
277
+ expect(body.refresh_token).toBe("example-old-basic-refresh");
276
278
  // Basic auth carries the client credentials — they must NOT be in the body
277
279
  expect(body.client_id).toBeUndefined();
278
280
  expect(body.client_secret).toBeUndefined();
279
281
  return Promise.resolve(
280
282
  Response.json({
281
- access_token: "new-basic-access",
283
+ access_token: "example-new-basic-access",
282
284
  token_type: "Bearer",
283
285
  expires_in: 3600,
284
- refresh_token: "new-basic-refresh",
286
+ refresh_token: "example-new-basic-refresh",
285
287
  }),
286
288
  );
287
289
  });
@@ -293,7 +295,7 @@ describe("OAuth credential bindings", () => {
293
295
  expect(bindings).toContainEqual(
294
296
  expect.objectContaining({
295
297
  configKey: "PHASE2_BASIC_OAUTH",
296
- value: "new-basic-access",
298
+ value: "example-new-basic-access",
297
299
  }),
298
300
  );
299
301
  });
@@ -323,7 +325,7 @@ describe("OAuth credential bindings", () => {
323
325
  action: "oauth-app-upsert",
324
326
  provider: "jira",
325
327
  clientId: "jira-client",
326
- clientSecret: "jira-secret",
328
+ clientSecret: "example-jira-secret",
327
329
  authorizeUrl: "https://oauth.example.test/authorize",
328
330
  tokenUrl: "https://oauth.example.test/token",
329
331
  scopes: [],
@@ -345,7 +347,7 @@ describe("OAuth credential bindings", () => {
345
347
  action: "oauth-app-upsert",
346
348
  provider: "phase2-tool-unsafe",
347
349
  clientId: "unsafe-client",
348
- clientSecret: "unsafe-secret",
350
+ clientSecret: "example-unsafe-secret",
349
351
  authorizeUrl: "https://oauth.example.test/authorize",
350
352
  tokenUrl: "http://127.0.0.1/token",
351
353
  scopes: [],
@@ -362,7 +364,7 @@ describe("OAuth credential bindings", () => {
362
364
  action: "oauth-app-upsert",
363
365
  provider: "phase2-tool-safe",
364
366
  clientId: "safe-client",
365
- clientSecret: "safe-secret",
367
+ clientSecret: "example-safe-secret",
366
368
  authorizeUrl: "https://oauth.example.test/authorize",
367
369
  tokenUrl: "https://oauth.example.test/token",
368
370
  scopes: ["read"],
@@ -377,8 +379,8 @@ describe("OAuth credential bindings", () => {
377
379
  test("failed OAuth token refresh skips only that binding, others still resolve", async () => {
378
380
  await upsertOAuthApp("phase2-broken", testApp("phase2-broken"));
379
381
  await storeOAuthTokens("phase2-broken", {
380
- accessToken: "stale-access-token",
381
- refreshToken: "stale-refresh-token",
382
+ accessToken: "example-stale-access-token",
383
+ refreshToken: "example-stale-refresh-token",
382
384
  expiresAt: new Date(Date.now() + 60 * 1000).toISOString(),
383
385
  });
384
386
  await upsertCredentialBinding({
@@ -419,7 +421,7 @@ describe("OAuth credential bindings", () => {
419
421
  test("revoked OAuth token skips binding resolution and list reports revoked", async () => {
420
422
  await upsertOAuthApp("phase2-missing", testApp("phase2-missing"));
421
423
  await storeOAuthTokens("phase2-missing", {
422
- accessToken: "soon-deleted",
424
+ accessToken: "example-soon-deleted",
423
425
  expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
424
426
  });
425
427
  const authorizationId = (await getOAuthTokens("phase2-missing"))!.id;
@@ -465,10 +467,10 @@ describe("OAuth credential bindings", () => {
465
467
  expect(String(init?.body)).toContain("grant_type=authorization_code");
466
468
  expect(String(init?.body)).toContain("code=callback-code");
467
469
  return Response.json({
468
- access_token: "callback-access-token",
470
+ access_token: "example-callback-access-token",
469
471
  token_type: "Bearer",
470
472
  expires_in: 3600,
471
- refresh_token: "callback-refresh-token",
473
+ refresh_token: "example-callback-refresh-token",
472
474
  scope: "read write",
473
475
  });
474
476
  }) as typeof fetch;
@@ -483,8 +485,8 @@ describe("OAuth credential bindings", () => {
483
485
  expect(res.status).toBe(200);
484
486
  expect(await res.text()).toContain("You can close this tab.");
485
487
  const tokens = await getOAuthTokens(provider);
486
- expect(tokens?.accessToken).toBe("callback-access-token");
487
- expect(tokens?.refreshToken).toBe("callback-refresh-token");
488
+ expect(tokens?.accessToken).toBe("example-callback-access-token");
489
+ expect(tokens?.refreshToken).toBe("example-callback-refresh-token");
488
490
  } finally {
489
491
  server.close();
490
492
  }
@@ -22,7 +22,7 @@ function restoreSlackAlertsChannel(): void {
22
22
 
23
23
  const testApp = {
24
24
  clientId: "test-client-id",
25
- clientSecret: "test-client-secret",
25
+ clientSecret: "example-test-client-secret",
26
26
  authorizeUrl: "https://example.com/oauth/authorize",
27
27
  tokenUrl: "https://example.com/oauth/token",
28
28
  redirectUri: "http://localhost:3013/callback",
@@ -78,13 +78,13 @@ describe("OAuth keepalive", () => {
78
78
 
79
79
  test("stopOAuthKeepalive waits for in-flight Jira refresh persistence", async () => {
80
80
  await storeOAuthTokens("linear", {
81
- accessToken: "linear-access",
82
- refreshToken: "linear-refresh",
81
+ accessToken: "example-linear-access",
82
+ refreshToken: "example-linear-refresh",
83
83
  expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
84
84
  });
85
85
  await storeOAuthTokens("jira", {
86
- accessToken: "old-jira-access",
87
- refreshToken: "old-jira-refresh",
86
+ accessToken: "example-old-jira-access",
87
+ refreshToken: "example-old-jira-refresh",
88
88
  expiresAt: new Date(Date.now() + 60 * 1000).toISOString(),
89
89
  });
90
90
 
@@ -102,10 +102,10 @@ describe("OAuth keepalive", () => {
102
102
  await tokenResponseReady;
103
103
  return new Response(
104
104
  JSON.stringify({
105
- access_token: "new-jira-access",
105
+ access_token: "example-new-jira-access",
106
106
  token_type: "Bearer",
107
107
  expires_in: 3600,
108
- refresh_token: "new-jira-refresh",
108
+ refresh_token: "example-new-jira-refresh",
109
109
  }),
110
110
  { status: 200, headers: { "Content-Type": "application/json" } },
111
111
  );
@@ -121,7 +121,7 @@ describe("OAuth keepalive", () => {
121
121
 
122
122
  await Promise.resolve();
123
123
  expect(stopResolved).toBe(false);
124
- expect((await getOAuthTokens("jira"))?.refreshToken).toBe("old-jira-refresh");
124
+ expect((await getOAuthTokens("jira"))?.refreshToken).toBe("example-old-jira-refresh");
125
125
 
126
126
  releaseTokenResponse();
127
127
  await stopPromise;
@@ -129,7 +129,7 @@ describe("OAuth keepalive", () => {
129
129
 
130
130
  expect(stopResolved).toBe(true);
131
131
  const tokens = await getOAuthTokens("jira");
132
- expect(tokens?.accessToken).toBe("new-jira-access");
133
- expect(tokens?.refreshToken).toBe("new-jira-refresh");
132
+ expect(tokens?.accessToken).toBe("example-new-jira-access");
133
+ expect(tokens?.refreshToken).toBe("example-new-jira-refresh");
134
134
  });
135
135
  });