@desplega.ai/agent-swarm 1.149.1 → 1.151.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (538) hide show
  1. package/README.md +18 -3
  2. package/dist/{acp-adapter-vhkzfpjg.js → acp-adapter-ex8hzjfc.js} +5 -5
  3. package/dist/{actions-9d2694yk.js → actions-2bgpyhww.js} +39 -11
  4. package/dist/{app-fq2ggynt.js → app-1706zhr1.js} +7 -7
  5. package/dist/{artifact-gj9arwrr.js → artifact-td4q4dch.js} +1 -1
  6. package/dist/{assistant-edb6n9nn.js → assistant-bavke5p7.js} +44 -20
  7. package/dist/{azure-openai-responses-cqar64rc.js → azure-openai-responses-f38x2avq.js} +13 -13
  8. package/dist/{boot-reembed-msweabbp.js → boot-reembed-3cmrrmpa.js} +9 -9
  9. package/dist/{boot-reembed-q5wd3tha.js → boot-reembed-nafcmmmc.js} +14 -16
  10. package/dist/{boot-scrub-logs-3g1az933.js → boot-scrub-logs-cd6a2sq0.js} +5 -5
  11. package/dist/{claude-adapter-v3rnzsdc.js → claude-adapter-wfp2gzvz.js} +15 -16
  12. package/dist/{claude-managed-adapter-qvsmh6mv.js → claude-managed-adapter-dsmkcrjy.js} +3 -3
  13. package/dist/{claude-sdk-session-qxrpsna1.js → claude-sdk-session-bht9jjak.js} +15 -16
  14. package/dist/{cli-5m0qmvdp.js → cli-0qb1z6s2.js} +1 -1
  15. package/dist/{cli-9d8ntetj.js → cli-2658f6at.js} +1 -1
  16. package/dist/{cli-7evafqvy.js → cli-2tbvf1z1.js} +85 -69
  17. package/dist/{cli-k351hv5k.js → cli-3v9xhjcn.js} +24 -12
  18. package/dist/{cli-1ebpar1q.js → cli-4wppfkcm.js} +350 -20
  19. package/dist/{cli-4260r1tg.js → cli-5jd2z7av.js} +97 -84
  20. package/dist/{cli-cv7s5zdq.js → cli-5tpgq60f.js} +9865 -715
  21. package/dist/{cli-6skz3rk8.js → cli-7tgcstn2.js} +9 -4
  22. package/dist/{cli-01g3x1ca.js → cli-9004vfdf.js} +108 -56
  23. package/dist/{cli-1c94wvcw.js → cli-a1z3h107.js} +124 -99
  24. package/dist/{cli-9br8ypfv.js → cli-czjtgfys.js} +2 -2
  25. package/dist/{cli-5my3bjsd.js → cli-d3p82erb.js} +7 -7
  26. package/dist/{cli-e29gmdmw.js → cli-dv6cdjs2.js} +2 -1
  27. package/dist/{cli-wby1xnnb.js → cli-f1wky6zp.js} +1 -1
  28. package/dist/{cli-zvz62chv.js → cli-fm4ytsdk.js} +4 -4
  29. package/dist/{cli-tg8qj8ee.js → cli-frcta2w4.js} +6 -6
  30. package/dist/{cli-7xx10h0a.js → cli-g69fdc9g.js} +2 -2
  31. package/dist/{cli-cmp8g3sw.js → cli-gbfwcd3k.js} +44 -9
  32. package/dist/{handlers-nsg0bcye.js → cli-gjyvhmmh.js} +97 -45
  33. package/dist/{cli-08b07b4r.js → cli-ht5rs63n.js} +1 -1
  34. package/dist/{cli-jecc01cb.js → cli-j4nv2wqy.js} +2 -4
  35. package/dist/{cli-cd60fv6j.js → cli-j9xczhaq.js} +1 -1
  36. package/dist/cli-pf9q3696.js +172 -0
  37. package/dist/{cli-xm87hzbw.js → cli-pgj4a5fb.js} +1 -1
  38. package/dist/{cli-jezx9b9c.js → cli-ppm4975n.js} +9 -3
  39. package/dist/{cli-3z634pqe.js → cli-q88st9aj.js} +2 -2
  40. package/dist/{cli-3sysyjve.js → cli-r2q6pevn.js} +142 -49
  41. package/dist/{cli-07jd68a1.js → cli-re8z5p8p.js} +1 -1
  42. package/dist/{cli-qgd4sqz5.js → cli-s14agm5s.js} +121 -14
  43. package/dist/{cli-svbrpf5q.js → cli-sjaae6ff.js} +9872 -424
  44. package/dist/{cli-73gq0zxn.js → cli-vwm416m6.js} +13 -13
  45. package/dist/{cli-4wtq5jjv.js → cli-wbyk465z.js} +1 -1
  46. package/dist/{cli-3apbzgyk.js → cli-z61ykvam.js} +19 -14
  47. package/dist/{cli-e06a8a7y.js → cli-zkxymas5.js} +4 -3
  48. package/dist/cli.js +26 -25
  49. package/dist/{codex-adapter-jyw7a91z.js → codex-adapter-jjjk8w4m.js} +8 -9
  50. package/dist/{codex-hook-hfrt9shr.js → codex-hook-8jexc34x.js} +3 -3
  51. package/dist/{codex-session-runner-bmngj0s5.js → codex-session-runner-nd6ayxkx.js} +8 -9
  52. package/dist/{commands-n755g391.js → commands-9v4psyq1.js} +5 -5
  53. package/dist/{db-s1cgh5gv.js → db-wnt58tpe.js} +5 -5
  54. package/dist/dispatcher-05jh1aqk.js +74 -0
  55. package/dist/{e2b-p04vmtx0.js → e2b-413b8t4v.js} +1 -1
  56. package/dist/{google-generative-ai-tsskx7te.js → google-generative-ai-ndjmj5fa.js} +7 -7
  57. package/dist/{google-vertex-ppw8ydpa.js → google-vertex-fr665tqs.js} +10 -10
  58. package/dist/handlers-tw90pkh5.js +65 -0
  59. package/dist/{hook-jf0xe8zh.js → hook-123e2scb.js} +11 -12
  60. package/dist/{hook-h9cqrm8q.js → hook-sxe3r349.js} +11 -12
  61. package/dist/{http-nc6pydw5.js → http-ecsar8ez.js} +1442 -581
  62. package/dist/{index-ezxkds2n.js → index-16js521z.js} +335 -107
  63. package/dist/{index-769nc012.js → index-hw26vj40.js} +25 -19
  64. package/dist/{index-0wdy6gwc.js → index-nnrbpcjp.js} +25 -17
  65. package/dist/index-ymn7em0p.js +25 -0
  66. package/dist/{index-x1zcj09z.js → index-zj518gf9.js} +26 -20
  67. package/dist/{keepalive-nesm3xb6.js → keepalive-asqtcm4y.js} +7 -7
  68. package/dist/{lead-bwy6t2za.js → lead-xbfr7fvt.js} +40 -48
  69. package/dist/{maintenance-8w393zf0.js → maintenance-qma55qvw.js} +9 -9
  70. package/dist/{oauth-refresh-sweep-sh8xjy08.js → oauth-refresh-sweep-3s04c6qw.js} +6 -6
  71. package/dist/{onboard-25ps29h1.js → onboard-drskd386.js} +13 -4
  72. package/dist/{openai-codex-responses-g7w48y30.js → openai-codex-responses-wy6a43wd.js} +13 -13
  73. package/dist/{openai-responses-nmeyptke.js → openai-responses-6xwf7bzg.js} +19 -19
  74. package/dist/{opencode-adapter-dce4wskd.js → opencode-adapter-28axqa09.js} +4 -4
  75. package/dist/{otel-impl-b93gxnz5.js → otel-impl-943c96er.js} +1 -1
  76. package/dist/{pi-mono-adapter-zvshk5cj.js → pi-mono-adapter-jcqt71cg.js} +17 -19
  77. package/dist/{pricing-refresh-5v56x7gb.js → pricing-refresh-mx51az05.js} +7 -7
  78. package/dist/{rbac-roles-x55cnezn.js → rbac-roles-78baecqd.js} +13 -9
  79. package/dist/{rbac-roles-0p0s6pbj.js → rbac-roles-wcmrg6sv.js} +7 -7
  80. package/dist/{render-v2-hyd45w8b.js → render-v2-8zjntgf5.js} +7 -7
  81. package/dist/{seed-pricing-49gbgn96.js → seed-pricing-jqjs6cws.js} +6 -6
  82. package/dist/{setup-qvq64vzq.js → setup-4pks0vfk.js} +2 -2
  83. package/dist/work-objects-wangt792.js +165 -0
  84. package/dist/{worker-scj60cxg.js → worker-p2mr422x.js} +40 -48
  85. package/openapi.json +1365 -268
  86. package/package.json +4 -3
  87. package/src/agentmail/handlers.ts +95 -66
  88. package/src/be/budget-refusal-notify.ts +1 -0
  89. package/src/be/db/tasks/read.ts +3 -0
  90. package/src/be/db/tasks/write.ts +13 -1
  91. package/src/be/db-client.ts +5 -0
  92. package/src/be/db.ts +15 -5
  93. package/src/be/extensions/db.ts +461 -0
  94. package/src/be/extensions/validate.ts +107 -0
  95. package/src/be/memory/boot-reembed.ts +17 -12
  96. package/src/be/memory/index.ts +12 -0
  97. package/src/be/memory/providers/openai-embedding.ts +4 -0
  98. package/src/be/memory/types.ts +2 -0
  99. package/src/be/migrations/153_deferred_task_wait_members.sql +25 -0
  100. package/src/be/migrations/154_routing_source.sql +3 -0
  101. package/src/be/migrations/155_extensions.sql +66 -0
  102. package/src/be/migrations/156_inbox_item_state_read_at.sql +7 -0
  103. package/src/be/rbac-roles.ts +3 -2
  104. package/src/be/scripts/typecheck.ts +59 -41
  105. package/src/be/seed/schedules-seeder.ts +25 -2
  106. package/src/be/seed/workflows-seeder.ts +17 -0
  107. package/src/be/seed-scripts/catalog/delegate.ts +3 -1
  108. package/src/be/seed-skills/bundled-files.generated.json +1 -1
  109. package/src/be/seed-skills/index.ts +7 -0
  110. package/src/be/steering.ts +1 -0
  111. package/src/be/swarm-config-guard.ts +3 -1
  112. package/src/commands/credential-refresh.ts +70 -0
  113. package/src/commands/onboard/compose-generator.ts +14 -2
  114. package/src/commands/onboard/env-generator.ts +7 -0
  115. package/src/commands/provider-credentials.ts +2 -25
  116. package/src/commands/runner.ts +24 -57
  117. package/src/extensions/apply-task-create.ts +135 -0
  118. package/src/extensions/bundle-path.ts +10 -0
  119. package/src/extensions/contract-runtime.ts +7 -0
  120. package/src/extensions/contract-types.generated.ts +4 -0
  121. package/src/extensions/contract.ts +270 -0
  122. package/src/extensions/ctx.ts +186 -0
  123. package/src/extensions/dispatcher.ts +479 -0
  124. package/src/extensions/identity.ts +44 -0
  125. package/src/extensions/lifecycle.ts +281 -0
  126. package/src/extensions/loader.ts +207 -0
  127. package/src/extensions/post-bridge.ts +161 -0
  128. package/src/github/handlers.ts +185 -140
  129. package/src/gitlab/handlers.ts +97 -77
  130. package/src/heartbeat/heartbeat.ts +155 -83
  131. package/src/http/agents.ts +1 -1
  132. package/src/http/all-routes.ts +1 -0
  133. package/src/http/approval-requests.ts +1 -0
  134. package/src/http/apps.ts +14 -9
  135. package/src/http/config.ts +4 -1
  136. package/src/http/core.ts +38 -2
  137. package/src/http/extensions.ts +547 -0
  138. package/src/http/inbox-state.ts +2 -0
  139. package/src/http/index.ts +41 -3
  140. package/src/http/mcp-bridge.ts +96 -62
  141. package/src/http/mcp.ts +1 -1
  142. package/src/http/script-runs.ts +5 -0
  143. package/src/http/status.ts +6 -4
  144. package/src/http/tasks.ts +51 -30
  145. package/src/integrations/kapso/inbound.ts +15 -10
  146. package/src/jira/sync.ts +26 -16
  147. package/src/linear/sync.ts +26 -16
  148. package/src/prompts/session-templates.ts +18 -13
  149. package/src/providers/claude-adapter.ts +21 -8
  150. package/src/rbac/admission.ts +1 -1
  151. package/src/rbac/elevated-agents.ts +24 -0
  152. package/src/rbac/legacy-policy.ts +35 -6
  153. package/src/rbac/permissions.ts +8 -0
  154. package/src/scheduler/deferred-task-waits.ts +138 -27
  155. package/src/scheduler/schedule-task.ts +54 -24
  156. package/src/scheduler/scheduler.ts +108 -125
  157. package/src/scripts-runtime/executors/native.ts +5 -1
  158. package/src/scripts-runtime/executors/types.ts +5 -0
  159. package/src/scripts-runtime/import-allowlist.ts +79 -19
  160. package/src/scripts-runtime/sdk-allowlist.ts +4 -0
  161. package/src/scripts-runtime/swarm-config.ts +8 -0
  162. package/src/scripts-runtime/swarm-sdk.ts +3 -0
  163. package/src/scripts-runtime/types/stdlib.d.ts +16 -3
  164. package/src/scripts-runtime/types/swarm-extension.d.ts +562 -0
  165. package/src/scripts-runtime/types/swarm-sdk.d.ts +16 -3
  166. package/src/server.ts +6 -0
  167. package/src/slack/HEURISTICS.md +3 -1
  168. package/src/slack/actions.ts +21 -16
  169. package/src/slack/app.ts +2 -0
  170. package/src/slack/assistant.ts +4 -12
  171. package/src/slack/blocks.ts +1 -1
  172. package/src/slack/handlers.ts +107 -19
  173. package/src/slack/inbound-files.ts +9 -5
  174. package/src/slack/render-v2.ts +188 -38
  175. package/src/slack/router.ts +13 -3
  176. package/src/slack/steering.ts +3 -3
  177. package/src/slack/thread-buffer.ts +66 -23
  178. package/src/slack/work-objects.test.ts +252 -0
  179. package/src/slack/work-objects.ts +118 -0
  180. package/src/tasks/errors.ts +9 -0
  181. package/src/tasks/sibling-awareness.ts +35 -1
  182. package/src/tasks/worker-follow-up.ts +67 -11
  183. package/src/tests/acp-adapter.test.ts +10 -10
  184. package/src/tests/agent-fs-live-url.test.ts +40 -0
  185. package/src/tests/agent-fs-provision-seeder.test.ts +12 -12
  186. package/src/tests/api-key-tracking.test.ts +18 -18
  187. package/src/tests/api-key.test.ts +4 -2
  188. package/src/tests/apps-rbac.test.ts +1 -1
  189. package/src/tests/apps-spike5.test.ts +1 -1
  190. package/src/tests/apps-sync-engine.test.ts +8 -8
  191. package/src/tests/apps-user-config.test.ts +1 -1
  192. package/src/tests/artifact-sdk.test.ts +8 -8
  193. package/src/tests/asset-key-mcp.test.ts +2 -0
  194. package/src/tests/automation-preflight-alert.test.ts +1 -1
  195. package/src/tests/base-prompt.test.ts +7 -6
  196. package/src/tests/budget-user-scope.test.ts +1 -1
  197. package/src/tests/budgets-routes.test.ts +1 -1
  198. package/src/tests/claude-adapter-binary.test.ts +22 -40
  199. package/src/tests/claude-adapter-otel.test.ts +13 -7
  200. package/src/tests/claude-adapter.test.ts +8 -6
  201. package/src/tests/claude-hook-credentials.test.ts +3 -3
  202. package/src/tests/claude-managed-adapter.test.ts +4 -4
  203. package/src/tests/claude-managed-setup.test.ts +3 -3
  204. package/src/tests/claude-sdk-lifecycle.test.ts +1 -1
  205. package/src/tests/claude-sdk-transport.test.ts +6 -6
  206. package/src/tests/claude-stop-hook.test.ts +8 -8
  207. package/src/tests/claude-worker-parity.test.ts +3 -3
  208. package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +5 -5
  209. package/src/tests/codex-adapter.test.ts +7 -5
  210. package/src/tests/codex-app-server.test.ts +2 -2
  211. package/src/tests/codex-login.test.ts +15 -15
  212. package/src/tests/codex-oauth-credential-info.test.ts +4 -4
  213. package/src/tests/codex-oauth-keep-warm.test.ts +4 -4
  214. package/src/tests/codex-oauth-refresh-lock.test.ts +1 -1
  215. package/src/tests/codex-oauth-storage.test.ts +7 -7
  216. package/src/tests/codex-pool.test.ts +1 -1
  217. package/src/tests/codex-steering-hook.test.ts +1 -1
  218. package/src/tests/codex-swarm-events.test.ts +1 -1
  219. package/src/tests/config-api-only-keys.test.ts +1 -1
  220. package/src/tests/config-session-auth.test.ts +2 -2
  221. package/src/tests/connection-embedded-auth.test.ts +20 -18
  222. package/src/tests/core-auth.test.ts +1 -1
  223. package/src/tests/create-page-tool.test.ts +3 -3
  224. package/src/tests/credential-refresh.test.ts +115 -0
  225. package/src/tests/credential-wait.test.ts +2 -2
  226. package/src/tests/credentials.test.ts +6 -4
  227. package/src/tests/db-queries-oauth.test.ts +40 -40
  228. package/src/tests/defer-task.test.ts +73 -8
  229. package/src/tests/deferred-task-wait-migration.test.ts +64 -0
  230. package/src/tests/deferred-task-wake.test.ts +349 -8
  231. package/src/tests/devin-adapter.test.ts +1 -1
  232. package/src/tests/devin-api.test.ts +1 -1
  233. package/src/tests/docs-index-footprint.test.js +3 -3
  234. package/src/tests/e2b-dispatch.test.ts +21 -19
  235. package/src/tests/e2e-claude-transport.test.ts +3 -3
  236. package/src/tests/e2e-redact.test.ts +6 -6
  237. package/src/tests/ensure-token.test.ts +68 -68
  238. package/src/tests/entrypoint-api-readiness.test.ts +1 -1
  239. package/src/tests/entrypoint-codex-oauth-seed.test.ts +13 -13
  240. package/src/tests/env-flag.test.ts +1 -0
  241. package/src/tests/events-http.test.ts +1 -1
  242. package/src/tests/extensions-db.test.ts +216 -0
  243. package/src/tests/extensions-dispatcher.test.ts +275 -0
  244. package/src/tests/extensions-example-heartbeat-remediate.test.ts +69 -0
  245. package/src/tests/extensions-example-mcp-install.test.ts +63 -0
  246. package/src/tests/extensions-example-no-exclamation-marks.test.ts +72 -0
  247. package/src/tests/extensions-example-rewrite-and-suppress.test.ts +70 -0
  248. package/src/tests/extensions-example-route-slack-channel.test.ts +217 -0
  249. package/src/tests/extensions-heartbeat.test.ts +291 -0
  250. package/src/tests/extensions-http.test.ts +431 -0
  251. package/src/tests/extensions-lead-equivalence.test.ts +49 -0
  252. package/src/tests/extensions-lifecycle.test.ts +209 -0
  253. package/src/tests/extensions-loader.test.ts +95 -0
  254. package/src/tests/extensions-mcp-tools.test.ts +245 -0
  255. package/src/tests/extensions-pre-task.test.ts +487 -0
  256. package/src/tests/extensions-run-context.test.ts +41 -0
  257. package/src/tests/extensions-tool-call.test.ts +288 -0
  258. package/src/tests/extensions-validate.test.ts +196 -0
  259. package/src/tests/fixtures/extensions/bad-import/hooks.ts +8 -0
  260. package/src/tests/fixtures/extensions/bad-import/manifest.json +9 -0
  261. package/src/tests/fixtures/extensions/bad-return-shape/hooks.ts +10 -0
  262. package/src/tests/fixtures/extensions/bad-return-shape/manifest.json +9 -0
  263. package/src/tests/fixtures/extensions/block-tasks-from-source/hooks.ts +22 -0
  264. package/src/tests/fixtures/extensions/block-tasks-from-source/manifest.json +9 -0
  265. package/src/tests/fixtures/extensions/ignore-channel/hooks.ts +22 -0
  266. package/src/tests/fixtures/extensions/ignore-channel/manifest.json +9 -0
  267. package/src/tests/fixtures/extensions/load.ts +10 -0
  268. package/src/tests/fixtures/extensions/minimal/hooks.ts +7 -0
  269. package/src/tests/fixtures/extensions/minimal/manifest.json +9 -0
  270. package/src/tests/fixtures/extensions/never-fail-long-tasks/hooks.ts +11 -0
  271. package/src/tests/fixtures/extensions/never-fail-long-tasks/manifest.json +9 -0
  272. package/src/tests/fixtures/extensions/no-exclamation-marks/hooks.ts +23 -0
  273. package/src/tests/fixtures/extensions/no-exclamation-marks/manifest.json +9 -0
  274. package/src/tests/fixtures/extensions/post-logger/hooks.ts +9 -0
  275. package/src/tests/fixtures/extensions/post-logger/manifest.json +9 -0
  276. package/src/tests/fixtures/extensions/priority-a/hooks.ts +7 -0
  277. package/src/tests/fixtures/extensions/priority-a/manifest.json +9 -0
  278. package/src/tests/fixtures/extensions/priority-b/hooks.ts +7 -0
  279. package/src/tests/fixtures/extensions/priority-b/manifest.json +9 -0
  280. package/src/tests/fixtures/extensions/record-only-on-tag/hooks.ts +16 -0
  281. package/src/tests/fixtures/extensions/record-only-on-tag/manifest.json +9 -0
  282. package/src/tests/fixtures/extensions/reserved-assets/hooks.ts +5 -0
  283. package/src/tests/fixtures/extensions/reserved-assets/manifest.json +10 -0
  284. package/src/tests/fixtures/extensions/rewrite-progress-prefix/hooks.ts +22 -0
  285. package/src/tests/fixtures/extensions/rewrite-progress-prefix/manifest.json +9 -0
  286. package/src/tests/fixtures/extensions/rewrite-task-priority/hooks.ts +7 -0
  287. package/src/tests/fixtures/extensions/rewrite-task-priority/manifest.json +9 -0
  288. package/src/tests/fixtures/extensions/route-channel-to-agent/hooks.ts +26 -0
  289. package/src/tests/fixtures/extensions/route-channel-to-agent/manifest.json +9 -0
  290. package/src/tests/fixtures/extensions/slow/hooks.ts +10 -0
  291. package/src/tests/fixtures/extensions/slow/manifest.json +9 -0
  292. package/src/tests/fixtures/extensions/suppress-lead-follow-up/hooks.ts +12 -0
  293. package/src/tests/fixtures/extensions/suppress-lead-follow-up/manifest.json +9 -0
  294. package/src/tests/fixtures/extensions/throws/hooks.ts +12 -0
  295. package/src/tests/fixtures/extensions/throws/manifest.json +9 -0
  296. package/src/tests/fixtures/extensions/worker-runtime/hooks.ts +5 -0
  297. package/src/tests/fixtures/extensions/worker-runtime/manifest.json +9 -0
  298. package/src/tests/fs-routes.test.ts +1 -1
  299. package/src/tests/gitlab-auth.test.ts +10 -10
  300. package/src/tests/harness-provider-resolution.test.ts +8 -5
  301. package/src/tests/heartbeat-reroute-decision.test.ts +1 -0
  302. package/src/tests/helper-credentials.test.ts +137 -0
  303. package/src/tests/http/context-routes.test.ts +2 -2
  304. package/src/tests/http-api-integration.test.ts +5 -2
  305. package/src/tests/http-users.test.ts +1 -1
  306. package/src/tests/identity-refresh.test.ts +2 -2
  307. package/src/tests/internal-ai/complete-structured.test.ts +2 -2
  308. package/src/tests/internal-ai/credentials.test.ts +19 -17
  309. package/src/tests/jira-metadata.test.ts +1 -1
  310. package/src/tests/jira-oauth.test.ts +5 -5
  311. package/src/tests/jira-sync.test.ts +1 -1
  312. package/src/tests/jira-webhook-lifecycle.test.ts +3 -3
  313. package/src/tests/jira-webhook.test.ts +2 -2
  314. package/src/tests/kapso-inbound.test.ts +2 -2
  315. package/src/tests/kv-http.test.ts +1 -1
  316. package/src/tests/kv-namespace-resolution.test.ts +1 -1
  317. package/src/tests/kv-page-proxy.test.ts +2 -2
  318. package/src/tests/launch-password-rejection.test.ts +2 -2
  319. package/src/tests/linear-webhook.test.ts +1 -1
  320. package/src/tests/mcp-oauth-dcr-reuse.test.ts +6 -6
  321. package/src/tests/mcp-oauth-ensure-token.test.ts +28 -22
  322. package/src/tests/mcp-oauth-manual-client.test.ts +16 -12
  323. package/src/tests/mcp-oauth-queries.test.ts +35 -32
  324. package/src/tests/mcp-oauth-resolve-secrets.test.ts +8 -8
  325. package/src/tests/mcp-oauth-wrapper.test.ts +20 -20
  326. package/src/tests/mcp-user-route.test.ts +1 -1
  327. package/src/tests/memory-edges.test.ts +1 -1
  328. package/src/tests/memory-edit-authorization.test.ts +32 -0
  329. package/src/tests/memory-rate-endpoint.test.ts +1 -1
  330. package/src/tests/memory-rate-tool.test.ts +2 -2
  331. package/src/tests/memory-rater-e2e.test.ts +1 -1
  332. package/src/tests/memory-rater-llm-summarizer.test.ts +3 -3
  333. package/src/tests/memory-rater-llm.test.ts +1 -1
  334. package/src/tests/model-control.test.ts +3 -0
  335. package/src/tests/multi-runtime-enabled-stats.test.ts +2 -2
  336. package/src/tests/multi-runtime-registration.test.ts +111 -17
  337. package/src/tests/oauth-access-token-tool.test.ts +18 -18
  338. package/src/tests/oauth-callback-flow.test.ts +8 -8
  339. package/src/tests/oauth-credential-bindings.test.ts +29 -27
  340. package/src/tests/oauth-keepalive.test.ts +10 -10
  341. package/src/tests/oauth-presets.test.ts +13 -5
  342. package/src/tests/oauth-refresh-failure.test.ts +9 -9
  343. package/src/tests/oauth-refresh-sweep.test.ts +20 -13
  344. package/src/tests/oauth-wrapper.test.ts +1 -1
  345. package/src/tests/onboard-compose.test.ts +47 -3
  346. package/src/tests/onboard-env.test.ts +26 -26
  347. package/src/tests/onboard-non-interactive.test.ts +4 -4
  348. package/src/tests/opencode-adapter.test.ts +1 -1
  349. package/src/tests/opencode-plugin.test.ts +2 -2
  350. package/src/tests/otel-session-cost-metrics.test.ts +1 -1
  351. package/src/tests/page-proxy-authed.test.ts +2 -2
  352. package/src/tests/page-proxy.test.ts +2 -2
  353. package/src/tests/page-session.test.ts +7 -7
  354. package/src/tests/page-viewer-auth.test.ts +2 -2
  355. package/src/tests/pages-authed-mode.test.ts +1 -1
  356. package/src/tests/pages-http.test.ts +1 -1
  357. package/src/tests/pages-password-mode.test.ts +1 -1
  358. package/src/tests/pages-public-authed-401.test.ts +1 -1
  359. package/src/tests/pages-public-html.test.ts +2 -2
  360. package/src/tests/pages-view-count.test.ts +1 -1
  361. package/src/tests/pi-mono-adapter.test.ts +10 -10
  362. package/src/tests/pi-mono-extension.test.ts +2 -2
  363. package/src/tests/preload.ts +5 -0
  364. package/src/tests/pricing-routes.test.ts +1 -1
  365. package/src/tests/profile-sync-warning.test.ts +8 -8
  366. package/src/tests/profile-sync.test.ts +8 -8
  367. package/src/tests/prompt-template-session.test.ts +36 -5
  368. package/src/tests/provider-process-group.test.ts +95 -4
  369. package/src/tests/providers/pi-cost.test.ts +1 -1
  370. package/src/tests/queue-stall-alarm.test.ts +1 -1
  371. package/src/tests/rbac-admission.test.ts +19 -4
  372. package/src/tests/rbac-charact-http.test.ts +1 -1
  373. package/src/tests/rbac-e2e-helpers.ts +1 -1
  374. package/src/tests/rbac-engine.test.ts +39 -0
  375. package/src/tests/realtime-room-auth.test.ts +1 -1
  376. package/src/tests/realtime-room-surfaces.test.ts +1 -1
  377. package/src/tests/reload-config.test.ts +45 -1
  378. package/src/tests/routing-affinity-inventory.test.ts +1 -1
  379. package/src/tests/routing-reason-contract.test.ts +76 -3
  380. package/src/tests/routing-reason-inventory.test.ts +11 -6
  381. package/src/tests/routing-source.test.ts +53 -0
  382. package/src/tests/runner-agent-fs-provision-retry.test.ts +1 -1
  383. package/src/tests/runner-context-preamble.test.ts +1 -1
  384. package/src/tests/runner-deployment-resume.test.ts +1 -1
  385. package/src/tests/runner-fallback-output.test.ts +1 -1
  386. package/src/tests/runner-identity-refresh.test.ts +1 -1
  387. package/src/tests/runner-skills-refresh.test.ts +1 -1
  388. package/src/tests/schedule-target-type.test.ts +3 -3
  389. package/src/tests/scheduled-tasks.test.ts +14 -5
  390. package/src/tests/scheduler-occurrence.test.ts +347 -0
  391. package/src/tests/script-apis-mcp.test.ts +1 -1
  392. package/src/tests/script-connections-http.test.ts +61 -58
  393. package/src/tests/script-connections-mcp.test.ts +1 -1
  394. package/src/tests/script-connections.test.ts +3 -1
  395. package/src/tests/script-runs-http.test.ts +15 -7
  396. package/src/tests/script-workflows-runtime-e2e.test.ts +1 -1
  397. package/src/tests/scripts-boot-reembed.test.ts +4 -0
  398. package/src/tests/scripts-embeddings.test.ts +4 -0
  399. package/src/tests/scripts-external-api.test.ts +1 -1
  400. package/src/tests/scripts-http.test.ts +1 -1
  401. package/src/tests/scripts-import-allowlist.test.ts +44 -1
  402. package/src/tests/scripts-mcp-e2e.test.ts +81 -1
  403. package/src/tests/scripts-only-gating.test.ts +4 -2
  404. package/src/tests/scripts-retention.test.ts +1 -1
  405. package/src/tests/scripts-runtime-identity.test.ts +2 -2
  406. package/src/tests/scripts-runtime-secret-egress.test.ts +1 -1
  407. package/src/tests/scripts-runtime.test.ts +6 -4
  408. package/src/tests/scripts-typecheck.test.ts +21 -0
  409. package/src/tests/sdk-allowlist.test.ts +1 -1
  410. package/src/tests/secret-scrubber.test.ts +38 -31
  411. package/src/tests/seed-registry.test.ts +46 -8
  412. package/src/tests/seed-schedules.test.ts +44 -9
  413. package/src/tests/seed-workflows.test.ts +21 -9
  414. package/src/tests/send-task-output-schema.test.ts +9 -1
  415. package/src/tests/send-task-requested-by.test.ts +1 -0
  416. package/src/tests/send-task-slack-routing-guard.test.ts +2 -0
  417. package/src/tests/session-costs-codex-recompute.test.ts +1 -1
  418. package/src/tests/session-costs-golden.test.ts +2 -2
  419. package/src/tests/session-costs-model-key-normalize.test.ts +2 -2
  420. package/src/tests/session-costs-recompute-all-providers.test.ts +1 -1
  421. package/src/tests/session-tokens.test.ts +1 -1
  422. package/src/tests/shutdown-error-scrubbing.test.ts +1 -1
  423. package/src/tests/slack-blocks.test.ts +12 -1
  424. package/src/tests/slack-file-tools-attachments.test.ts +1 -1
  425. package/src/tests/slack-inbound-files.test.ts +222 -86
  426. package/src/tests/slack-reaction-config.test.ts +5 -4
  427. package/src/tests/slack-read-boundaries.test.ts +1 -1
  428. package/src/tests/slack-render-v2.test.ts +196 -4
  429. package/src/tests/slack-router.test.ts +17 -2
  430. package/src/tests/slack-steering.test.ts +19 -0
  431. package/src/tests/status.test.ts +19 -7
  432. package/src/tests/steering-core.test.ts +1 -1
  433. package/src/tests/steering-enabled.test.ts +6 -8
  434. package/src/tests/steering-transport.test.ts +4 -4
  435. package/src/tests/store-progress-output-guidance.test.ts +34 -0
  436. package/src/tests/swarm-tool-result-gate.test.ts +11 -11
  437. package/src/tests/swarm-x-tool.test.ts +7 -5
  438. package/src/tests/sync-ai-toolbox-skills.test.ts +19 -0
  439. package/src/tests/task-supersede-resume.test.ts +1 -1
  440. package/src/tests/task-tool-preload-mcp.test.ts +4 -1
  441. package/src/tests/task-tools-ctx.test.ts +2 -0
  442. package/src/tests/tasks-requested-by-filter.test.ts +2 -2
  443. package/src/tests/telemetry-init.test.ts +11 -3
  444. package/src/tests/tool-annotations.test.ts +1 -1
  445. package/src/tests/tool-output-agent-id.test.ts +1 -0
  446. package/src/tests/tool-registrar-no-input.test.ts +42 -1
  447. package/src/tests/tracker-fold.test.ts +7 -7
  448. package/src/tests/tracker-tools.test.ts +3 -3
  449. package/src/tests/ui-followup-lead-delegation.test.ts +1 -0
  450. package/src/tests/unified-oauth-migration.test.ts +5 -5
  451. package/src/tests/user-token-rest-auth.test.ts +1 -1
  452. package/src/tests/user-token-routes.test.ts +1 -1
  453. package/src/tests/whoami-route.test.ts +1 -1
  454. package/src/tests/workflow-agent-task.test.ts +15 -13
  455. package/src/tests/workflow-ctx.test.ts +1 -1
  456. package/src/tests/workflow-e2e.test.ts +1 -1
  457. package/src/tests/workflow-engine-v2.test.ts +3 -1
  458. package/src/tests/workflow-executors.test.ts +2 -2
  459. package/src/tests/workflow-http-v2.test.ts +8 -6
  460. package/src/tests/workflow-input-redaction.test.ts +7 -5
  461. package/src/tests/workflow-integration-io.test.ts +2 -2
  462. package/src/tests/workflow-llm.test.ts +5 -5
  463. package/src/tests/workflow-registry.test.ts +1 -1
  464. package/src/tests/workflow-swarm-script.test.ts +1 -1
  465. package/src/tests/workflow-triggers-v2.test.ts +23 -21
  466. package/src/tests/x-composio.test.ts +9 -7
  467. package/src/tests/x402-client.test.ts +1 -1
  468. package/src/tests/x402-config.test.ts +28 -41
  469. package/src/tools/defer-task.ts +156 -24
  470. package/src/tools/extension-common.ts +84 -0
  471. package/src/tools/extension-install.ts +65 -0
  472. package/src/tools/extension-list.ts +66 -0
  473. package/src/tools/script-common.ts +43 -18
  474. package/src/tools/send-task.ts +87 -105
  475. package/src/tools/skills/skill-publish.ts +1 -0
  476. package/src/tools/store-progress.ts +1 -1
  477. package/src/tools/task-action.ts +43 -22
  478. package/src/tools/task-tool-ctx.ts +2 -0
  479. package/src/tools/templates.ts +2 -1
  480. package/src/tools/tool-config.ts +3 -1
  481. package/src/tools/utils.ts +140 -16
  482. package/src/types.ts +144 -0
  483. package/src/utils/constants.ts +7 -1
  484. package/src/utils/credentials.test.ts +16 -16
  485. package/src/utils/multi-runtime.ts +2 -2
  486. package/src/utils/steering-enabled.ts +4 -4
  487. package/src/workflows/executors/agent-task.ts +18 -3
  488. package/templates/ai-toolbox.manifest.json +7 -1
  489. package/templates/extensions/README.md +17 -0
  490. package/templates/extensions/notify-on-complete/README.md +11 -0
  491. package/templates/extensions/notify-on-complete/hooks.ts +61 -0
  492. package/templates/extensions/notify-on-complete/manifest.json +7 -0
  493. package/templates/extensions/require-ticket-ref/README.md +11 -0
  494. package/templates/extensions/require-ticket-ref/hooks.ts +30 -0
  495. package/templates/extensions/require-ticket-ref/manifest.json +7 -0
  496. package/templates/extensions/require-verification-note/README.md +11 -0
  497. package/templates/extensions/require-verification-note/hooks.ts +32 -0
  498. package/templates/extensions/require-verification-note/manifest.json +7 -0
  499. package/templates/schedules/daily-hn-briefing/config.json +1 -1
  500. package/templates/schedules/gtm-weekly-review/config.json +1 -1
  501. package/templates/schedules/weekly-code-health-reports/config.json +1 -1
  502. package/templates/schedules/weekly-dependabot-triage/config.json +1 -1
  503. package/templates/schedules/weekly-dora-metrics/config.json +1 -1
  504. package/templates/schedules/weekly-harness-upgrade-check/config.json +1 -1
  505. package/templates/skills/delegate-work/files/scripts/codex-exec.sh +1 -1
  506. package/templates/skills/scheduling/content.md +2 -0
  507. package/templates/skills/serply-search/SKILL.md +95 -0
  508. package/templates/skills/serply-search/config.json +13 -0
  509. package/templates/skills/serply-search/content.md +90 -0
  510. package/templates/skills/swarm-extensions/config.json +14 -0
  511. package/templates/skills/swarm-extensions/content.md +120 -0
  512. package/templates/skills/swarm-scripts/SKILL.md +2 -2
  513. package/templates/skills/swarm-scripts/content.md +2 -2
  514. package/templates/workflows/claude-code-changelog-watch/config.json +1 -1
  515. package/templates/workflows/gsc-topic-miner/config.json +1 -1
  516. package/templates/workflows/linear-drain-loop/config.json +1 -1
  517. package/templates/workflows/llm-safe-release-context/config.json +1 -1
  518. package/templates/workflows/ralph-loop/config.json +1 -1
  519. package/dist/cli-7fehefdf.js +0 -562
  520. package/dist/cli-ayvy5kde.js +0 -164
  521. package/dist/cli-ddfw1mc4.js +0 -4322
  522. package/dist/cli-hzqmgcm2.js +0 -3066
  523. package/dist/cli-j4d4f6hv.js +0 -338
  524. package/dist/cli-qgm2pfpq.js +0 -6377
  525. package/dist/cli-sdzq01t9.js +0 -823
  526. package/dist/cli-xvkmedgn.js +0 -332
  527. package/dist/cli-y3pq4v9g.js +0 -664
  528. package/dist/{anthropic-messages-vs2rabzp.js → anthropic-messages-2y8nktar.js} +19 -19
  529. package/dist/{claude-managed-setup-f5pmsyrp.js → claude-managed-setup-48dwg9bv.js} +3 -3
  530. package/dist/{cli-81r683bv.js → cli-ch38q5z4.js} +0 -0
  531. package/dist/{cli-6664w7y4.js → cli-kj76p1ez.js} +8 -8
  532. package/dist/{cli-c71mg51n.js → cli-r2fpe7cx.js} +5 -5
  533. package/dist/{cli-4xz3pmrq.js → cli-y6x0gqtg.js} +16 -16
  534. package/dist/{index-aa3sa6s8.js → index-2wsdsnmm.js} +1 -1
  535. package/dist/{mistral-conversations-4ryk7h83.js → mistral-conversations-qhr84ph3.js} +9 -9
  536. package/dist/{openai-completions-0bqmsajw.js → openai-completions-32rdwmze.js} +19 -19
  537. package/dist/{openrouter-images-qx18fyp8.js → openrouter-images-9f9ek4rw.js} +3 -3
  538. package/dist/{pi-messages-79jvzz1d.js → pi-messages-b1mbr6gp.js} +4 -4
@@ -28,7 +28,7 @@ describe("resolveCodexLoginConfig", () => {
28
28
 
29
29
  it("prompts for api url and api key in interactive mode", async () => {
30
30
  const promptText = mock(async () => "https://swarm.example.com");
31
- const promptSecret = mock(async () => "super-secret");
31
+ const promptSecret = mock(async () => "example-super-secret");
32
32
 
33
33
  const result = await resolveCodexLoginConfig([], {
34
34
  env: {},
@@ -39,7 +39,7 @@ describe("resolveCodexLoginConfig", () => {
39
39
 
40
40
  expect(result).toEqual({
41
41
  apiUrl: "https://swarm.example.com",
42
- apiKey: "super-secret",
42
+ apiKey: "example-super-secret",
43
43
  });
44
44
  expect(promptText).toHaveBeenCalledWith("Swarm API URL", "http://localhost:3013");
45
45
  expect(promptSecret).toHaveBeenCalledWith(
@@ -56,7 +56,7 @@ describe("resolveCodexLoginConfig", () => {
56
56
  const result = await resolveCodexLoginConfig([], {
57
57
  env: {
58
58
  MCP_BASE_URL: "https://env.example.com",
59
- API_KEY: "env-secret",
59
+ API_KEY: "example-env-secret",
60
60
  },
61
61
  isInteractive: true,
62
62
  promptText,
@@ -65,11 +65,11 @@ describe("resolveCodexLoginConfig", () => {
65
65
 
66
66
  expect(result).toEqual({
67
67
  apiUrl: "https://env.example.com",
68
- apiKey: "env-secret",
68
+ apiKey: "example-env-secret",
69
69
  });
70
70
  expect(promptSecret).toHaveBeenCalledWith(
71
71
  "Swarm API key",
72
- "env-secret",
72
+ "example-env-secret",
73
73
  "Press Enter to use AGENT_SWARM_API_KEY/API_KEY from the environment",
74
74
  );
75
75
  });
@@ -83,11 +83,11 @@ describe("resolveCodexLoginConfig", () => {
83
83
  });
84
84
 
85
85
  const result = await resolveCodexLoginConfig(
86
- ["--api-url", "https://flag.example.com", "--api-key", "flag-secret"],
86
+ ["--api-url", "https://flag.example.com", "--api-key", "example-flag-secret"],
87
87
  {
88
88
  env: {
89
89
  MCP_BASE_URL: "https://env.example.com",
90
- API_KEY: "env-secret",
90
+ API_KEY: "example-env-secret",
91
91
  },
92
92
  isInteractive: true,
93
93
  promptText,
@@ -97,7 +97,7 @@ describe("resolveCodexLoginConfig", () => {
97
97
 
98
98
  expect(result).toEqual({
99
99
  apiUrl: "https://flag.example.com",
100
- apiKey: "flag-secret",
100
+ apiKey: "example-flag-secret",
101
101
  });
102
102
  expect(promptText).not.toHaveBeenCalled();
103
103
  expect(promptSecret).not.toHaveBeenCalled();
@@ -107,7 +107,7 @@ describe("resolveCodexLoginConfig", () => {
107
107
  const promptText = mock(async () => {
108
108
  throw new Error("should not prompt for api url");
109
109
  });
110
- const promptSecret = mock(async () => "prompted-secret");
110
+ const promptSecret = mock(async () => "example-prompted-secret");
111
111
 
112
112
  const result = await resolveCodexLoginConfig(["--api-url", "https://flag.example.com"], {
113
113
  env: {},
@@ -118,7 +118,7 @@ describe("resolveCodexLoginConfig", () => {
118
118
 
119
119
  expect(result).toEqual({
120
120
  apiUrl: "https://flag.example.com",
121
- apiKey: "prompted-secret",
121
+ apiKey: "example-prompted-secret",
122
122
  });
123
123
  expect(promptText).not.toHaveBeenCalled();
124
124
  expect(promptSecret).toHaveBeenCalledTimes(1);
@@ -186,7 +186,7 @@ describe("runCodexLogin", () => {
186
186
  await runCodexLogin([], {
187
187
  resolveConfig: async () => ({
188
188
  apiUrl: "http://localhost:3013",
189
- apiKey: "test-key",
189
+ apiKey: "example-test-key",
190
190
  slot: 3,
191
191
  }),
192
192
  login: mock(async () => ({
@@ -214,7 +214,7 @@ describe("runCodexLogin", () => {
214
214
  await runCodexLogin([], {
215
215
  resolveConfig: async () => ({
216
216
  apiUrl: "http://localhost:3013",
217
- apiKey: "test-key",
217
+ apiKey: "example-test-key",
218
218
  slot: undefined,
219
219
  }),
220
220
  login: mock(async () => ({
@@ -245,7 +245,7 @@ describe("runCodexLogin", () => {
245
245
  await runCodexLogin([], {
246
246
  resolveConfig: async () => ({
247
247
  apiUrl: "http://localhost:3013",
248
- apiKey: "test-key",
248
+ apiKey: "example-test-key",
249
249
  slot: 101,
250
250
  }),
251
251
  login: mock(async () => {
@@ -274,7 +274,7 @@ describe("runCodexLogin", () => {
274
274
  await runCodexLogin([], {
275
275
  resolveConfig: async () => ({
276
276
  apiUrl: "http://localhost:3013",
277
- apiKey: "test-key",
277
+ apiKey: "example-test-key",
278
278
  slot: 10,
279
279
  }),
280
280
  login: mock(async () => ({
@@ -306,7 +306,7 @@ describe("runCodexLogin", () => {
306
306
  await runCodexLogin([], {
307
307
  resolveConfig: async () => ({
308
308
  apiUrl: "http://localhost:3013",
309
- apiKey: "test-key",
309
+ apiKey: "example-test-key",
310
310
  slot: undefined,
311
311
  }),
312
312
  login: mock(async () => {
@@ -31,7 +31,7 @@ import { join } from "node:path";
31
31
  import { resolveCodexOAuthCredentialInfo } from "../commands/runner";
32
32
 
33
33
  const MOCK_API_URL = "http://localhost:3013";
34
- const MOCK_API_KEY = "test-api-key";
34
+ const MOCK_API_KEY = "example-test-api-key";
35
35
 
36
36
  const originalFetch = globalThis.fetch;
37
37
  const originalHome = process.env.HOME;
@@ -65,9 +65,9 @@ async function writeStandaloneAuthJson(): Promise<void> {
65
65
  auth_mode: "chatgpt",
66
66
  OPENAI_API_KEY: null,
67
67
  tokens: {
68
- id_token: "id-standalone",
69
- access_token: "access-standalone",
70
- refresh_token: "refresh-standalone",
68
+ id_token: "example-id-standalone",
69
+ access_token: "example-access-standalone",
70
+ refresh_token: "example-refresh-standalone",
71
71
  account_id: "acct-standalone",
72
72
  },
73
73
  last_refresh: new Date().toISOString(),
@@ -24,7 +24,7 @@ const originalApiKey = process.env.AGENT_SWARM_API_KEY;
24
24
 
25
25
  beforeAll(async () => {
26
26
  initDb(TEST_DB_PATH);
27
- process.env.AGENT_SWARM_API_KEY = "test-api-key";
27
+ process.env.AGENT_SWARM_API_KEY = "example-test-api-key";
28
28
 
29
29
  lockServer = createServer((req, res) => {
30
30
  const url = new URL(req.url ?? "/", "http://internal");
@@ -159,8 +159,8 @@ describe("POST /api/oauth/keep-warm/codex", () => {
159
159
  setFetchForTesting(async () => {
160
160
  return new Response(
161
161
  JSON.stringify({
162
- access_token: "at_keepwarm",
163
- refresh_token: "rt_keepwarm",
162
+ access_token: "example-at_keepwarm",
163
+ refresh_token: "example-rt_keepwarm",
164
164
  expires_in: 864000,
165
165
  }),
166
166
  { status: 200, headers: { "Content-Type": "application/json" } },
@@ -173,7 +173,7 @@ describe("POST /api/oauth/keep-warm/codex", () => {
173
173
  const body = JSON.parse(captured.body) as { results: Array<Record<string, unknown>> };
174
174
  expect(body.results).toHaveLength(1);
175
175
  expect(body.results[0]).toMatchObject({ slot: 1, outcome: "refreshed" });
176
- expect(slots.get(1)?.access).toBe("at_keepwarm");
176
+ expect(slots.get(1)?.access).toBe("example-at_keepwarm");
177
177
  });
178
178
 
179
179
  it("skips a slot with an active codex-auth-watch bench marker", async () => {
@@ -31,7 +31,7 @@ import type { CodexOAuthCredentials } from "../providers/codex-oauth/types.js";
31
31
 
32
32
  const TEST_DB_PATH = "./test-codex-oauth-refresh-lock.sqlite";
33
33
  const MOCK_API_URL = "http://localhost:3013";
34
- const MOCK_API_KEY = "test-api-key";
34
+ const MOCK_API_KEY = "example-test-api-key";
35
35
 
36
36
  process.env.SECRETS_ENCRYPTION_KEY = Buffer.alloc(32, 3).toString("base64");
37
37
 
@@ -12,7 +12,7 @@ import {
12
12
  import type { CodexOAuthCredentials } from "../providers/codex-oauth/types.js";
13
13
 
14
14
  const MOCK_API_URL = "http://localhost:3013";
15
- const MOCK_API_KEY = "test-api-key";
15
+ const MOCK_API_KEY = "example-test-api-key";
16
16
 
17
17
  const mockCreds: CodexOAuthCredentials = {
18
18
  access: "at_test123",
@@ -500,8 +500,8 @@ describe("getValidCodexOAuth", () => {
500
500
  async () =>
501
501
  new Response(
502
502
  JSON.stringify({
503
- access_token: "at_refreshed",
504
- refresh_token: "rt_refreshed",
503
+ access_token: "example-at_refreshed",
504
+ refresh_token: "example-rt_refreshed",
505
505
  expires_in: 3600,
506
506
  }),
507
507
  { status: 200 },
@@ -509,7 +509,7 @@ describe("getValidCodexOAuth", () => {
509
509
  );
510
510
 
511
511
  const result = await getValidCodexOAuth(MOCK_API_URL, MOCK_API_KEY, 0);
512
- expect(result?.access).toBe("at_refreshed");
512
+ expect(result?.access).toBe("example-at_refreshed");
513
513
  expect(putCapturedKey).toBe("codex_oauth_0");
514
514
  });
515
515
 
@@ -601,8 +601,8 @@ describe("getValidCodexOAuth", () => {
601
601
  async () =>
602
602
  new Response(
603
603
  JSON.stringify({
604
- access_token: "at_keepwarm_refreshed",
605
- refresh_token: "rt_keepwarm_refreshed",
604
+ access_token: "example-at_keepwarm_refreshed",
605
+ refresh_token: "example-rt_keepwarm_refreshed",
606
606
  expires_in: 3600,
607
607
  }),
608
608
  { status: 200 },
@@ -612,7 +612,7 @@ describe("getValidCodexOAuth", () => {
612
612
  const result = await getValidCodexOAuth(MOCK_API_URL, MOCK_API_KEY, 0, {
613
613
  maxAgeMs: 7 * 24 * 60 * 60 * 1000,
614
614
  });
615
- expect(result?.access).toBe("at_keepwarm_refreshed");
615
+ expect(result?.access).toBe("example-at_keepwarm_refreshed");
616
616
  expect(putCapturedKey).toBe("codex_oauth_0");
617
617
  });
618
618
 
@@ -30,7 +30,7 @@ import type { CodexOAuthCredentials } from "../providers/codex-oauth/types.js";
30
30
  // ─── Fixtures ────────────────────────────────────────────────────────────────
31
31
 
32
32
  const MOCK_API_URL = "http://localhost:3013";
33
- const MOCK_API_KEY = "test-api-key";
33
+ const MOCK_API_KEY = "example-test-api-key";
34
34
  const FUTURE = Date.now() + 3_600_000;
35
35
 
36
36
  function makeJwt(userId: string, accountId: string): string {
@@ -9,7 +9,7 @@ import { CHILD_PROCESS_TEST_BUDGET_MS, expectChildOk, runChild } from "./test-pr
9
9
 
10
10
  const config: CodexHookConfig = {
11
11
  apiUrl: "http://steering.test",
12
- apiKey: "test-key",
12
+ apiKey: "example-test-key",
13
13
  agentId: "11111111-1111-4111-8111-111111111111",
14
14
  };
15
15
 
@@ -19,7 +19,7 @@ const originalFetch = globalThis.fetch;
19
19
  function buildOpts(override: Partial<CodexSwarmEventHandlerOpts> = {}): CodexSwarmEventHandlerOpts {
20
20
  return {
21
21
  apiUrl: "http://test-api",
22
- apiKey: "test-key",
22
+ apiKey: "example-test-key",
23
23
  agentId: "agent-1",
24
24
  taskId: "task-1",
25
25
  abortRef: { current: null },
@@ -18,7 +18,7 @@ import { listenOnFreePort } from "./test-net";
18
18
  // WITHOUT agentId — so the bootstrap admin key reached every worker.
19
19
 
20
20
  const TEST_DB_PATH = "./test-config-api-only-keys.sqlite";
21
- const API_KEY = "test-config-key";
21
+ const API_KEY = "example-test-config-key";
22
22
  const BOOTSTRAP_KEY = "API_AGENT_FS_API_KEY";
23
23
  const BOOTSTRAP_VALUE = "af_bootstrap_secret_should_never_leak";
24
24
 
@@ -7,8 +7,8 @@ import { handleSessions } from "../http/sessions";
7
7
  import { getPathSegments, parseQueryParams } from "../http/utils";
8
8
  import { listenOnFreePort } from "./test-net";
9
9
 
10
- const API_KEY = "config-session-test-operator";
11
- const SECRET = "config-session-test-secret-value";
10
+ const API_KEY = "example-config-session-test-operator";
11
+ const SECRET = "example-config-session-test-secret-value";
12
12
  let server: Server;
13
13
  let baseUrl: string;
14
14
  let workerId: string;
@@ -55,7 +55,7 @@ const savedEnv = { ...process.env };
55
55
 
56
56
  beforeEach(() => {
57
57
  clearVolatileSecretsForTesting();
58
- process.env.AGENT_SWARM_API_KEY = "embedded-auth-test-key";
58
+ process.env.AGENT_SWARM_API_KEY = "example-embedded-auth-test-key";
59
59
  delete process.env.API_KEY;
60
60
  process.env.MCP_BASE_URL = "http://localhost:3013";
61
61
  });
@@ -101,7 +101,7 @@ describe("embedded connection auth", () => {
101
101
  kind: "graphql",
102
102
  baseUrl: "https://api.vendor.test/graphql",
103
103
  allowedHosts: ["api.vendor.test"],
104
- auth: { type: "bearer", secret: "test-tok-123" },
104
+ auth: { type: "bearer", secret: "example-test-tok-123" },
105
105
  });
106
106
  createdConnectionIds.push(connection.id);
107
107
 
@@ -124,16 +124,16 @@ describe("embedded connection auth", () => {
124
124
  );
125
125
  expect(raw?.isSecret).toBe(1);
126
126
  expect(raw?.encrypted).toBe(1);
127
- expect(raw?.value).not.toBe("test-tok-123");
127
+ expect(raw?.value).not.toBe("example-test-tok-123");
128
128
  // Decrypts back to plaintext on read.
129
129
  expect((await getSwarmConfigs({ key: "connection.bearerVendor.secret" }))[0]?.value).toBe(
130
- "test-tok-123",
130
+ "example-test-tok-123",
131
131
  );
132
132
 
133
133
  // The broker registers the resolved secret with the scrubber so logs/output
134
134
  // only ever show the placeholder — never the raw value.
135
135
  await buildScriptCredentialBindings({});
136
- expect(scrubSecrets("token=test-tok-123")).toContain(
136
+ expect(scrubSecrets("token=example-test-tok-123")).toContain(
137
137
  "[REDACTED:connection.bearerVendor.secret]",
138
138
  );
139
139
  });
@@ -202,7 +202,7 @@ describe("embedded connection auth", () => {
202
202
  if (!app) throw new Error("app not created");
203
203
  const authorization = await upsertAuthorization({
204
204
  appId: app.id,
205
- accessToken: "oauth-access-token",
205
+ accessToken: "example-oauth-access-token",
206
206
  status: "active",
207
207
  });
208
208
 
@@ -313,7 +313,7 @@ describe("embedded connection auth", () => {
313
313
  kind: "graphql",
314
314
  baseUrl: "https://api.vendor.test/graphql",
315
315
  allowedHosts: ["api.vendor.test"],
316
- auth: { type: "bearer", secret: "slug-secret-1" },
316
+ auth: { type: "bearer", secret: "example-slug-secret-1" },
317
317
  });
318
318
  createdConnectionIds.push(connection.id);
319
319
  expect(await getSwarmConfigs({ key: "connection.slugOne.secret" })).toHaveLength(1);
@@ -324,17 +324,19 @@ describe("embedded connection auth", () => {
324
324
  kind: "graphql",
325
325
  baseUrl: "https://api.vendor.test/graphql",
326
326
  allowedHosts: ["api.vendor.test"],
327
- auth: { type: "bearer", secret: "slug-secret-2" },
327
+ auth: { type: "bearer", secret: "example-slug-secret-2" },
328
328
  });
329
329
  expect(renamed.authConfigKey).toBe("connection.slugTwo.secret");
330
330
  // Old derived secret is gone; the new one holds the new value.
331
331
  expect(await getSwarmConfigs({ key: "connection.slugOne.secret" })).toHaveLength(0);
332
332
  expect((await getSwarmConfigs({ key: "connection.slugTwo.secret" }))[0]?.value).toBe(
333
- "slug-secret-2",
333
+ "example-slug-secret-2",
334
334
  );
335
335
  // Stale key no longer scrubbed; new key is.
336
336
  await buildScriptCredentialBindings({});
337
- expect(scrubSecrets("v=slug-secret-2")).toContain("[REDACTED:connection.slugTwo.secret]");
337
+ expect(scrubSecrets("v=example-slug-secret-2")).toContain(
338
+ "[REDACTED:connection.slugTwo.secret]",
339
+ );
338
340
  });
339
341
 
340
342
  test("switching an inline-secret connection to oauth deletes the derived inline secret", async () => {
@@ -351,7 +353,7 @@ describe("embedded connection auth", () => {
351
353
  if (!app) throw new Error("app not created");
352
354
  const authorization = await upsertAuthorization({
353
355
  appId: app.id,
354
- accessToken: "oauth-access-token",
356
+ accessToken: "example-oauth-access-token",
355
357
  status: "active",
356
358
  });
357
359
 
@@ -360,7 +362,7 @@ describe("embedded connection auth", () => {
360
362
  kind: "graphql",
361
363
  baseUrl: "https://api.vendor.test/graphql",
362
364
  allowedHosts: ["api.vendor.test"],
363
- auth: { type: "bearer", secret: "switch-secret" },
365
+ auth: { type: "bearer", secret: "example-switch-secret" },
364
366
  });
365
367
  createdConnectionIds.push(connection.id);
366
368
  expect(await getSwarmConfigs({ key: "connection.switchVendor.secret" })).toHaveLength(1);
@@ -387,7 +389,7 @@ describe("embedded connection auth", () => {
387
389
  kind: "graphql",
388
390
  baseUrl: "https://api.vendor.test/graphql",
389
391
  allowedHosts: ["api.vendor.test"],
390
- auth: { type: "bearer", secret: "keep-secret" },
392
+ auth: { type: "bearer", secret: "example-keep-secret" },
391
393
  });
392
394
  createdConnectionIds.push(connection.id);
393
395
 
@@ -402,7 +404,7 @@ describe("embedded connection auth", () => {
402
404
  });
403
405
  expect(updated.authConfigKey).toBe("connection.keepVendor.secret");
404
406
  expect((await getSwarmConfigs({ key: "connection.keepVendor.secret" }))[0]?.value).toBe(
405
- "keep-secret",
407
+ "example-keep-secret",
406
408
  );
407
409
  });
408
410
 
@@ -413,7 +415,7 @@ describe("embedded connection auth", () => {
413
415
  kind: "graphql",
414
416
  baseUrl: "https://api.vendor.test/graphql",
415
417
  allowedHosts: ["api.vendor.test"],
416
- auth: { type: "bearer", secret: "rename-secret" },
418
+ auth: { type: "bearer", secret: "example-rename-secret" },
417
419
  });
418
420
  createdConnectionIds.push(connection.id);
419
421
  expect(await getSwarmConfigs({ key: "connection.renameOne.secret" })).toHaveLength(1);
@@ -689,7 +691,7 @@ describe("embedded connection auth", () => {
689
691
  kind: "openapi",
690
692
  baseUrl: `http://127.0.0.1:${server.port}`,
691
693
  openapiSpecJson: openapiSpec(server.port),
692
- auth: { type: "bearer", secret: "e2e-secret-xyz" },
694
+ auth: { type: "bearer", secret: "example-e2e-secret-xyz" },
693
695
  });
694
696
  createdConnectionIds.push(connection.id);
695
697
  expect(connection.generationError).toBeNull();
@@ -708,9 +710,9 @@ describe("embedded connection auth", () => {
708
710
 
709
711
  expect(output.error).toBeUndefined();
710
712
  expect(output.result).toEqual({ ok: true });
711
- expect(observedAuth).toBe("Bearer e2e-secret-xyz");
713
+ expect(observedAuth).toBe("Bearer example-e2e-secret-xyz");
712
714
  // The raw secret never appears in script output/logs — only the placeholder.
713
- expect(JSON.stringify(output)).not.toContain("e2e-secret-xyz");
715
+ expect(JSON.stringify(output)).not.toContain("example-e2e-secret-xyz");
714
716
  } finally {
715
717
  server.stop(true);
716
718
  }
@@ -15,7 +15,7 @@ import "../http/trackers/linear";
15
15
  import "../http/workflows";
16
16
  import { listenOnFreePort } from "./test-net";
17
17
 
18
- const API_KEY = "test-secret-key";
18
+ const API_KEY = "example-test-secret-key";
19
19
 
20
20
  function createTestServer(apiKey: string): Server {
21
21
  return createHttpServer(async (req: IncomingMessage, res: ServerResponse) => {
@@ -184,14 +184,14 @@ describe("create_page MCP tool", () => {
184
184
  body: "secret",
185
185
  contentType: "text/html",
186
186
  authMode: "password",
187
- password: "open-sesame",
187
+ password: "example-open-sesame",
188
188
  },
189
189
  fakeMeta,
190
190
  );
191
191
  const row = await getPageBySlug(agentId, "pw-tool");
192
192
  expect(row?.passwordHash).toBeDefined();
193
- expect(row?.passwordHash).not.toBe("open-sesame");
194
- expect(await Bun.password.verify("open-sesame", row!.passwordHash!)).toBe(true);
193
+ expect(row?.passwordHash).not.toBe("example-open-sesame");
194
+ expect(await Bun.password.verify("example-open-sesame", row!.passwordHash!)).toBe(true);
195
195
  });
196
196
  });
197
197
 
@@ -0,0 +1,115 @@
1
+ import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
2
+ import {
3
+ CREDENTIAL_RETRY_INTERVAL_MS,
4
+ type CredentialRefreshState,
5
+ refreshCredentialStatus,
6
+ } from "../commands/credential-refresh";
7
+ import * as credentials from "../commands/provider-credentials";
8
+ import type { AgentCredStatus } from "../types";
9
+
10
+ const api = { apiUrl: "http://unused.test", apiKey: "test", agentId: crypto.randomUUID() };
11
+ const ready: AgentCredStatus = {
12
+ ready: true,
13
+ missing: [],
14
+ satisfiedBy: "test",
15
+ hint: null,
16
+ liveTest: null,
17
+ latestModel: null,
18
+ reportedAt: 1,
19
+ reportKind: "post_task",
20
+ bedrock: null,
21
+ acp: null,
22
+ };
23
+
24
+ describe("runner credential refresh", () => {
25
+ let state: CredentialRefreshState;
26
+ let build: ReturnType<typeof spyOn<typeof credentials, "buildCredStatusReport">>;
27
+ let send: ReturnType<typeof spyOn<typeof credentials, "sendCredStatusReport">>;
28
+
29
+ beforeEach(() => {
30
+ state = { harnessProvider: "claude", ready: true, lastRefreshAt: 0, inFlight: false };
31
+ build = spyOn(credentials, "buildCredStatusReport").mockResolvedValue(ready);
32
+ send = spyOn(credentials, "sendCredStatusReport").mockResolvedValue(undefined);
33
+ });
34
+
35
+ afterEach(() => mock.restore());
36
+
37
+ test("a negative boot snapshot recovers on the retry interval", async () => {
38
+ state.ready = false;
39
+ await refreshCredentialStatus(api, state, "claude", {}, CREDENTIAL_RETRY_INTERVAL_MS - 1);
40
+ expect(build).not.toHaveBeenCalled();
41
+ await refreshCredentialStatus(api, state, "claude", {}, CREDENTIAL_RETRY_INTERVAL_MS);
42
+ expect(send).toHaveBeenCalledTimes(1);
43
+ expect(state.ready).toBe(true);
44
+ });
45
+
46
+ test("a failed readiness write is throttled and retried even when the snapshot is ready", async () => {
47
+ send.mockRejectedValueOnce(new Error("HTTP 503"));
48
+ await expect(refreshCredentialStatus(api, state, "pi", {}, 1)).rejects.toThrow("HTTP 503");
49
+ await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS);
50
+ expect(send).toHaveBeenCalledTimes(1);
51
+ await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS + 1);
52
+ expect(send).toHaveBeenCalledTimes(2);
53
+ expect(state.ready).toBe(true);
54
+ await refreshCredentialStatus(api, state, "pi", {}, 10 * CREDENTIAL_RETRY_INTERVAL_MS);
55
+ expect(build).toHaveBeenCalledTimes(2);
56
+ });
57
+
58
+ test("a failed snapshot build is retried without another provider change", async () => {
59
+ build.mockRejectedValueOnce(new Error("probe failed"));
60
+ await expect(refreshCredentialStatus(api, state, "pi", {}, 1)).rejects.toThrow("probe failed");
61
+ expect(send).not.toHaveBeenCalled();
62
+ await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS);
63
+ expect(build).toHaveBeenCalledTimes(1);
64
+ await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS + 1);
65
+ expect(send).toHaveBeenCalledTimes(1);
66
+ expect(state.ready).toBe(true);
67
+ });
68
+
69
+ test("CRED_CHECK_DISABLE suppresses provider changes, recovery, and Bedrock refresh", async () => {
70
+ state.ready = false;
71
+ await refreshCredentialStatus(
72
+ api,
73
+ state,
74
+ "pi",
75
+ { CRED_CHECK_DISABLE: "1", BEDROCK_AUTH_MODE: "sdk" },
76
+ 600_000,
77
+ );
78
+ expect(build).not.toHaveBeenCalled();
79
+ expect(send).not.toHaveBeenCalled();
80
+ });
81
+
82
+ test("slow reports cannot overlap or apply an invalidated provider snapshot", async () => {
83
+ let finishBuild!: (snapshot: AgentCredStatus) => void;
84
+ build.mockImplementationOnce(
85
+ () =>
86
+ new Promise((resolve) => {
87
+ finishBuild = resolve;
88
+ }),
89
+ );
90
+ const pending = refreshCredentialStatus(api, state, "pi", {}, 1);
91
+ await refreshCredentialStatus(api, state, "pi", {}, 600_000);
92
+ expect(build).toHaveBeenCalledTimes(1);
93
+ // Same invalidation the runner performs when it swaps adapters mid-check.
94
+ state.harnessProvider = null;
95
+ await refreshCredentialStatus(api, state, "acp", {}, 600_001);
96
+ expect(build).toHaveBeenCalledTimes(1);
97
+ finishBuild(ready);
98
+ await pending;
99
+ expect(send).not.toHaveBeenCalled();
100
+ await refreshCredentialStatus(api, state, "acp", {}, 600_002);
101
+ expect(build).toHaveBeenCalledTimes(2);
102
+ expect(send).toHaveBeenCalledTimes(1);
103
+ });
104
+
105
+ test("Bedrock enumeration retains its five-minute refresh when ready", async () => {
106
+ state.harnessProvider = "pi";
107
+ const env = { BEDROCK_AUTH_MODE: "sdk" };
108
+ await refreshCredentialStatus(api, state, "pi", env, 300_000);
109
+ expect(build).not.toHaveBeenCalled();
110
+ await refreshCredentialStatus(api, state, "pi", env, 300_001);
111
+ expect(build).toHaveBeenCalledTimes(1);
112
+ await refreshCredentialStatus(api, state, "pi", env, 300_002);
113
+ expect(build).toHaveBeenCalledTimes(1);
114
+ });
115
+ });
@@ -221,7 +221,7 @@ describe("awaitCredentials", () => {
221
221
  const status = await awaitCredentials({
222
222
  provider: "claude",
223
223
  initialEnv: {},
224
- refreshEnv: async () => ({ CLAUDE_CODE_OAUTH_TOKEN: "fresh-tok" }),
224
+ refreshEnv: async () => ({ CLAUDE_CODE_OAUTH_TOKEN: "example-fresh-tok" }),
225
225
  sleep: async () => {},
226
226
  log: log.fn,
227
227
  backoff: { initialMs: 1, maxMs: 1, maxWaitSeconds: 0 },
@@ -229,7 +229,7 @@ describe("awaitCredentials", () => {
229
229
 
230
230
  expect(status.ready).toBe(true);
231
231
  // After the loop returns ready, process.env reflects the fresh value.
232
- expect(process.env.CLAUDE_CODE_OAUTH_TOKEN).toBe("fresh-tok");
232
+ expect(process.env.CLAUDE_CODE_OAUTH_TOKEN).toBe("example-fresh-tok");
233
233
  });
234
234
 
235
235
  test("backoff config falls back to env-var defaults when override absent", async () => {
@@ -12,7 +12,7 @@ describe("validateClaudeCredentials", () => {
12
12
  });
13
13
 
14
14
  test("returns 'api_key' when only ANTHROPIC_API_KEY is set", () => {
15
- expect(validateClaudeCredentials({ ANTHROPIC_API_KEY: "sk-ant-123" })).toBe("api_key");
15
+ expect(validateClaudeCredentials({ ANTHROPIC_API_KEY: "example-sk-ant-123" })).toBe("api_key");
16
16
  });
17
17
 
18
18
  test("prefers oauth over api_key when both are set", () => {
@@ -52,19 +52,21 @@ describe("validateOpencodeCredentials", () => {
52
52
  });
53
53
 
54
54
  test("returns 'openrouter_api_key' when OPENROUTER_API_KEY is set", () => {
55
- expect(validateOpencodeCredentials({ OPENROUTER_API_KEY: "sk-or-123" })).toBe(
55
+ expect(validateOpencodeCredentials({ OPENROUTER_API_KEY: "example-sk-or-123" })).toBe(
56
56
  "openrouter_api_key",
57
57
  );
58
58
  });
59
59
 
60
60
  test("returns 'anthropic_api_key' when only ANTHROPIC_API_KEY is set", () => {
61
- expect(validateOpencodeCredentials({ ANTHROPIC_API_KEY: "sk-ant-123" })).toBe(
61
+ expect(validateOpencodeCredentials({ ANTHROPIC_API_KEY: "example-sk-ant-123" })).toBe(
62
62
  "anthropic_api_key",
63
63
  );
64
64
  });
65
65
 
66
66
  test("returns 'openai_api_key' when only OPENAI_API_KEY is set", () => {
67
- expect(validateOpencodeCredentials({ OPENAI_API_KEY: "sk-openai-123" })).toBe("openai_api_key");
67
+ expect(validateOpencodeCredentials({ OPENAI_API_KEY: "example-sk-openai-123" })).toBe(
68
+ "openai_api_key",
69
+ );
68
70
  });
69
71
 
70
72
  test("returns 'auth_file' when auth.json exists and no env vars are set", () => {