@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
@@ -40,7 +40,7 @@ describe("OAuth Apps CRUD", () => {
40
40
  test("upsertOAuthApp creates a new app", async () => {
41
41
  await upsertOAuthApp("test-provider", {
42
42
  clientId: "client-123",
43
- clientSecret: "secret-456",
43
+ clientSecret: "example-secret-456",
44
44
  authorizeUrl: "https://example.com/authorize",
45
45
  tokenUrl: "https://example.com/token",
46
46
  redirectUri: "https://example.com/callback",
@@ -51,7 +51,7 @@ describe("OAuth Apps CRUD", () => {
51
51
  expect(app).not.toBeNull();
52
52
  expect(app!.provider).toBe("test-provider");
53
53
  expect(app!.clientId).toBe("client-123");
54
- expect(app!.clientSecret).toBe("secret-456");
54
+ expect(app!.clientSecret).toBe("example-secret-456");
55
55
  expect(app!.authorizeUrl).toBe("https://example.com/authorize");
56
56
  expect(app!.tokenUrl).toBe("https://example.com/token");
57
57
  expect(app!.redirectUri).toBe("https://example.com/callback");
@@ -62,7 +62,7 @@ describe("OAuth Apps CRUD", () => {
62
62
  test("upsertOAuthApp updates existing app on conflict", async () => {
63
63
  await upsertOAuthApp("test-provider", {
64
64
  clientId: "client-updated",
65
- clientSecret: "secret-updated",
65
+ clientSecret: "example-secret-updated",
66
66
  authorizeUrl: "https://example.com/authorize-v2",
67
67
  tokenUrl: "https://example.com/token-v2",
68
68
  redirectUri: "https://example.com/callback-v2",
@@ -80,7 +80,7 @@ describe("OAuth Apps CRUD", () => {
80
80
  test("multiple providers can coexist", async () => {
81
81
  await upsertOAuthApp("provider-a", {
82
82
  clientId: "a-client",
83
- clientSecret: "a-secret",
83
+ clientSecret: "example-a-secret",
84
84
  authorizeUrl: "https://a.com/authorize",
85
85
  tokenUrl: "https://a.com/token",
86
86
  redirectUri: "https://a.com/callback",
@@ -88,7 +88,7 @@ describe("OAuth Apps CRUD", () => {
88
88
  });
89
89
  await upsertOAuthApp("provider-b", {
90
90
  clientId: "b-client",
91
- clientSecret: "b-secret",
91
+ clientSecret: "example-b-secret",
92
92
  authorizeUrl: "https://b.com/authorize",
93
93
  tokenUrl: "https://b.com/token",
94
94
  redirectUri: "https://b.com/callback",
@@ -162,8 +162,8 @@ describe("OAuth Tokens CRUD", () => {
162
162
 
163
163
  const futureDate = new Date(Date.now() + 3600000).toISOString();
164
164
  await storeOAuthTokens("token-test", {
165
- accessToken: "access-abc",
166
- refreshToken: "refresh-xyz",
165
+ accessToken: "example-access-abc",
166
+ refreshToken: "example-refresh-xyz",
167
167
  expiresAt: futureDate,
168
168
  scope: "read,write",
169
169
  });
@@ -171,94 +171,94 @@ describe("OAuth Tokens CRUD", () => {
171
171
  const tokens = await getOAuthTokens("token-test");
172
172
  expect(tokens).not.toBeNull();
173
173
  expect(tokens!.provider).toBe("token-test");
174
- expect(tokens!.accessToken).toBe("access-abc");
175
- expect(tokens!.refreshToken).toBe("refresh-xyz");
174
+ expect(tokens!.accessToken).toBe("example-access-abc");
175
+ expect(tokens!.refreshToken).toBe("example-refresh-xyz");
176
176
  expect(tokens!.scope).toBe("read,write");
177
177
  });
178
178
 
179
179
  test("storeOAuthTokens updates existing tokens (upsert)", async () => {
180
180
  const futureDate = new Date(Date.now() + 7200000).toISOString();
181
181
  await storeOAuthTokens("token-test", {
182
- accessToken: "access-updated",
182
+ accessToken: "example-access-updated",
183
183
  expiresAt: futureDate,
184
184
  });
185
185
 
186
186
  const tokens = await getOAuthTokens("token-test");
187
- expect(tokens!.accessToken).toBe("access-updated");
187
+ expect(tokens!.accessToken).toBe("example-access-updated");
188
188
  // refreshToken should be preserved (COALESCE)
189
- expect(tokens!.refreshToken).toBe("refresh-xyz");
189
+ expect(tokens!.refreshToken).toBe("example-refresh-xyz");
190
190
  });
191
191
 
192
192
  test("updateOAuthTokensAfterRefresh replaces the rotated refresh token atomically", async () => {
193
193
  const futureDate = new Date(Date.now() + 7200000).toISOString();
194
194
  await storeOAuthTokens("token-test", {
195
- accessToken: "access-before-refresh",
196
- refreshToken: "refresh-before-refresh",
195
+ accessToken: "example-access-before-refresh",
196
+ refreshToken: "example-refresh-before-refresh",
197
197
  expiresAt: new Date(Date.now() + 60000).toISOString(),
198
198
  });
199
199
  const observed = (await getOAuthTokens("token-test"))!;
200
200
 
201
- await updateOAuthTokensAfterRefresh("token-test", "refresh-before-refresh", {
202
- accessToken: "access-after-refresh",
203
- refreshToken: "refresh-after-refresh",
201
+ await updateOAuthTokensAfterRefresh("token-test", "example-refresh-before-refresh", {
202
+ accessToken: "example-access-after-refresh",
203
+ refreshToken: "example-refresh-after-refresh",
204
204
  expiresAt: futureDate,
205
205
  scope: "read,write",
206
206
  expectedTokenVersion: observed.tokenVersion,
207
207
  });
208
208
 
209
209
  const tokens = await getOAuthTokens("token-test");
210
- expect(tokens!.accessToken).toBe("access-after-refresh");
211
- expect(tokens!.refreshToken).toBe("refresh-after-refresh");
210
+ expect(tokens!.accessToken).toBe("example-access-after-refresh");
211
+ expect(tokens!.refreshToken).toBe("example-refresh-after-refresh");
212
212
  expect(tokens!.expiresAt).toBe(futureDate);
213
213
  expect(tokens!.scope).toBe("read,write");
214
214
  });
215
215
 
216
216
  test("updateOAuthTokensAfterRefresh refuses to overwrite a concurrently rotated token", async () => {
217
217
  await storeOAuthTokens("token-test", {
218
- accessToken: "access-current",
219
- refreshToken: "refresh-current",
218
+ accessToken: "example-access-current",
219
+ refreshToken: "example-refresh-current",
220
220
  expiresAt: new Date(Date.now() + 60000).toISOString(),
221
221
  });
222
222
 
223
223
  await expect(
224
224
  updateOAuthTokensAfterRefresh("token-test", "refresh-stale", {
225
- accessToken: "access-stale-result",
226
- refreshToken: "refresh-stale-result",
225
+ accessToken: "example-access-stale-result",
226
+ refreshToken: "example-refresh-stale-result",
227
227
  expiresAt: new Date(Date.now() + 7200000).toISOString(),
228
228
  }),
229
229
  ).rejects.toThrow(/stored refresh token changed during refresh/);
230
230
 
231
231
  const tokens = await getOAuthTokens("token-test");
232
- expect(tokens!.accessToken).toBe("access-current");
233
- expect(tokens!.refreshToken).toBe("refresh-current");
232
+ expect(tokens!.accessToken).toBe("example-access-current");
233
+ expect(tokens!.refreshToken).toBe("example-refresh-current");
234
234
  });
235
235
 
236
236
  test("updateOAuthTokensAfterRefresh rejects a stale version even when the refresh token is unchanged", async () => {
237
237
  await storeOAuthTokens("token-test", {
238
- accessToken: "access-observed",
239
- refreshToken: "refresh-stable",
238
+ accessToken: "example-access-observed",
239
+ refreshToken: "example-refresh-stable",
240
240
  expiresAt: new Date(Date.now() + 60000).toISOString(),
241
241
  });
242
242
  const observed = (await getOAuthTokens("token-test"))!;
243
243
 
244
244
  await storeOAuthTokens("token-test", {
245
- accessToken: "access-concurrent-winner",
246
- refreshToken: "refresh-stable",
245
+ accessToken: "example-access-concurrent-winner",
246
+ refreshToken: "example-refresh-stable",
247
247
  expiresAt: new Date(Date.now() + 3600000).toISOString(),
248
248
  });
249
249
 
250
250
  await expect(
251
- updateOAuthTokensAfterRefresh("token-test", "refresh-stable", {
252
- accessToken: "access-stale-result",
253
- refreshToken: "refresh-stale-result",
251
+ updateOAuthTokensAfterRefresh("token-test", "example-refresh-stable", {
252
+ accessToken: "example-access-stale-result",
253
+ refreshToken: "example-refresh-stale-result",
254
254
  expiresAt: new Date(Date.now() + 7200000).toISOString(),
255
255
  expectedTokenVersion: observed.tokenVersion,
256
256
  }),
257
257
  ).rejects.toThrow(/no rows updated/);
258
258
 
259
259
  const tokens = await getOAuthTokens("token-test");
260
- expect(tokens?.accessToken).toBe("access-concurrent-winner");
261
- expect(tokens?.refreshToken).toBe("refresh-stable");
260
+ expect(tokens?.accessToken).toBe("example-access-concurrent-winner");
261
+ expect(tokens?.refreshToken).toBe("example-refresh-stable");
262
262
  });
263
263
 
264
264
  test("listAuthorizationSweepRows normalizes legacy bare expiresAt values", async () => {
@@ -282,15 +282,15 @@ describe("OAuth Tokens CRUD", () => {
282
282
  test("deleteOAuthTokens revokes in place and reconnect reuses the authorization id", async () => {
283
283
  await upsertOAuthApp("disconnect-continuity", {
284
284
  clientId: "client-dc",
285
- clientSecret: "secret-dc",
285
+ clientSecret: "example-secret-dc",
286
286
  authorizeUrl: "https://example.com/authorize",
287
287
  tokenUrl: "https://example.com/token",
288
288
  redirectUri: "https://example.com/callback",
289
289
  scopes: "read",
290
290
  });
291
291
  await storeOAuthTokens("disconnect-continuity", {
292
- accessToken: "access-original",
293
- refreshToken: "refresh-original",
292
+ accessToken: "example-access-original",
293
+ refreshToken: "example-refresh-original",
294
294
  expiresAt: new Date(Date.now() + 3600000).toISOString(),
295
295
  });
296
296
  const originalId = await getDefaultAuthorizationIdForProvider("disconnect-continuity");
@@ -303,15 +303,15 @@ describe("OAuth Tokens CRUD", () => {
303
303
  expect(await getDefaultAuthorizationIdForProvider("disconnect-continuity")).toBe(originalId);
304
304
 
305
305
  await storeOAuthTokens("disconnect-continuity", {
306
- accessToken: "access-reconnected",
307
- refreshToken: "refresh-reconnected",
306
+ accessToken: "example-access-reconnected",
307
+ refreshToken: "example-refresh-reconnected",
308
308
  expiresAt: new Date(Date.now() + 3600000).toISOString(),
309
309
  });
310
310
  // Reconnect reuses the same authorization id.
311
311
  expect(await getDefaultAuthorizationIdForProvider("disconnect-continuity")).toBe(originalId);
312
312
  const reconnected = await getOAuthTokens("disconnect-continuity");
313
313
  expect(reconnected?.id).toBe(originalId);
314
- expect(reconnected?.accessToken).toBe("access-reconnected");
314
+ expect(reconnected?.accessToken).toBe("example-access-reconnected");
315
315
  });
316
316
  });
317
317
 
@@ -19,6 +19,7 @@ import {
19
19
  completeTask,
20
20
  createAgent,
21
21
  createTaskExtended,
22
+ createUser,
22
23
  createWorkflow,
23
24
  createWorkflowRun,
24
25
  createWorkflowRunStep,
@@ -183,14 +184,30 @@ describe("defer-task handler", () => {
183
184
 
184
185
  const stored = await getTaskById(task.id);
185
186
  expect(stored?.status).toBe("completed");
186
- // Summary first, then the deferral status line, then the checks.
187
- expect(stored?.output).toBe(
187
+ // Human-facing output: one line, `Deferred until {date} {time} ({link}) -> {desc}`.
188
+ // No requestedByUserId is set on this task, so it falls back to UTC and
189
+ // labels it explicitly.
190
+ const shortId = schedule.id.slice(0, 8);
191
+ expect(stored?.output).toMatch(
192
+ /^Deferred until (today|tomorrow|\d{2}-\d{2}) \d{2}:\d{2}:\d{2} UTC \(/,
193
+ );
194
+ expect(stored?.output).toContain(
195
+ `([${shortId}](https://app.agent-swarm.dev/schedules/${schedule.id})) -> deploy 42 is still running`,
196
+ );
197
+ expect(stored?.output).not.toContain(schedule.nextRunAt!);
198
+ expect(stored?.output).not.toContain("Checks:");
199
+ expect(stored?.output).not.toContain("- smoke tests pass");
200
+ expect(stored?.output).not.toContain("Pending:");
201
+ expect(stored?.output).not.toContain(SUMMARY);
202
+
203
+ // Full detail (ISO timestamp, schedule id, checks) lands in the task log.
204
+ const logs = (await getLogsByTaskId(task.id)).filter(
205
+ (log) => log.eventType === "task_progress",
206
+ );
207
+ expect(logs).toHaveLength(1);
208
+ expect(logs[0]!.newValue).toBe(
188
209
  `${SUMMARY}\n\nDeferred until ${schedule.nextRunAt} (schedule ${schedule.id}). Pending: deploy 42 is still running\n\nChecks:\n- deploy 42 status is green\n- smoke tests pass`,
189
210
  );
190
- expect(stored?.output).toContain("Pending: deploy 42 is still running");
191
- expect(stored?.output).toContain(schedule.nextRunAt!);
192
- expect(stored?.output).toContain(schedule.id);
193
- expect(stored?.output).toContain("- smoke tests pass");
194
211
  });
195
212
 
196
213
  test("runAt path is honoured verbatim", async () => {
@@ -423,8 +440,56 @@ describe("defer-task handler", () => {
423
440
  meta(),
424
441
  )) as DeferTaskResult;
425
442
  expect(result.structuredContent.success).toBe(true);
426
- expect((await getTaskById(task.id))?.output).toBe(
427
- `${SUMMARY}\n\nDeferred until ${result.structuredContent.nextRunAt} (schedule ${result.structuredContent.scheduleId}). Pending: pending`,
443
+ const stored = await getTaskById(task.id);
444
+ const shortId = result.structuredContent.scheduleId!.slice(0, 8);
445
+ expect(stored?.output).toMatch(
446
+ /^Deferred until (today|tomorrow|\d{2}-\d{2}) \d{2}:\d{2}:\d{2} UTC \(/,
447
+ );
448
+ expect(stored?.output).toContain(`([${shortId}](`);
449
+ expect(stored?.output).toContain(") -> pending");
450
+ expect(stored?.output).not.toContain(SUMMARY);
451
+ });
452
+
453
+ test("human-facing output strips a repeated Pending: prefix and caps a long note", async () => {
454
+ const task = await startedTask("verbose note");
455
+ const longNote = `Pending: ${"x".repeat(300)}\nsecond line is dropped`;
456
+ const result = (await buildTool().handler(
457
+ { taskId: task.id, delayMs: 60_000, summary: SUMMARY, note: longNote },
458
+ meta(),
459
+ )) as DeferTaskResult;
460
+
461
+ expect(result.structuredContent.success).toBe(true);
462
+ const stored = await getTaskById(task.id);
463
+ // No doubled "Pending: Pending:", no second line, capped with an ellipsis.
464
+ expect(stored?.output).not.toContain("Pending: Pending:");
465
+ expect(stored?.output).not.toContain("second line is dropped");
466
+ expect(stored?.output).toContain(`-> ${"x".repeat(99)}…`);
467
+
468
+ // The full untrimmed note still reaches the task log and the wake-up task.
469
+ const logs = (await getLogsByTaskId(task.id)).filter(
470
+ (log) => log.eventType === "task_progress",
471
+ );
472
+ expect(logs[0]!.newValue).toContain(`Pending: ${longNote}`);
473
+ const schedules = await schedulesForTask(task.id);
474
+ expect(schedules[0]!.taskTemplate).toContain(longNote);
475
+ });
476
+
477
+ test("human-facing time renders in the requester's timezone, unlabelled, when one is on file", async () => {
478
+ const user = await createUser({ name: "Requester", timezone: "America/New_York" });
479
+ const task = await startedTask("waiting on requester", agentId, {
480
+ requestedByUserId: user.id,
481
+ });
482
+
483
+ const result = (await buildTool().handler(
484
+ { taskId: task.id, delayMs: 60_000, summary: SUMMARY, note: "pending" },
485
+ meta(),
486
+ )) as DeferTaskResult;
487
+
488
+ expect(result.structuredContent.success).toBe(true);
489
+ const stored = await getTaskById(task.id);
490
+ // A real timezone is on file: no explicit "UTC" label on the time.
491
+ expect(stored?.output).toMatch(
492
+ /^Deferred until (today|tomorrow|\d{2}-\d{2}) \d{2}:\d{2}:\d{2} \(/,
428
493
  );
429
494
  });
430
495
 
@@ -0,0 +1,64 @@
1
+ import { Database } from "bun:sqlite";
2
+ import { expect, test } from "bun:test";
3
+
4
+ test("multi-task wait migration preserves legacy claims, audit fields, and current watched IDs", async () => {
5
+ const db = new Database(":memory:");
6
+ try {
7
+ db.exec("PRAGMA foreign_keys = ON; CREATE TABLE scheduled_tasks (id TEXT PRIMARY KEY)");
8
+ db.exec(
9
+ await Bun.file(
10
+ new URL("../be/migrations/150_deferred_task_waits.sql", import.meta.url),
11
+ ).text(),
12
+ );
13
+ for (const status of ["pending", "fired"]) {
14
+ db.run("INSERT INTO scheduled_tasks VALUES (?)", [status]);
15
+ db.run(
16
+ `INSERT INTO deferred_task_waits
17
+ (scheduleId, taskId, eventName, status, firedBy, childTaskId, resolvedAt,
18
+ created_at, updated_at, created_by, updated_by)
19
+ VALUES (?, ?, 'settled', ?, ?, ?, ?, 'created', 'updated', 'creator', 'updater')`,
20
+ [
21
+ status,
22
+ `resumed-${status}`,
23
+ status,
24
+ status === "fired" ? "ceiling" : null,
25
+ status === "fired" ? "child" : null,
26
+ status === "fired" ? "resolved" : null,
27
+ ],
28
+ );
29
+ }
30
+ const before = db
31
+ .query("SELECT * FROM deferred_task_waits ORDER BY scheduleId")
32
+ .all() as Record<string, unknown>[];
33
+ const sql = await Bun.file(
34
+ new URL("../be/migrations/153_deferred_task_wait_members.sql", import.meta.url),
35
+ ).text();
36
+ db.transaction(() => db.exec(sql))();
37
+ for (const { taskId, ...wait } of before) {
38
+ expect(
39
+ db
40
+ .query("SELECT * FROM deferred_task_waits WHERE scheduleId = ?")
41
+ .get(wait.scheduleId as string),
42
+ ).toEqual({ ...wait, mode: "all" });
43
+ expect(
44
+ db
45
+ .query("SELECT * FROM deferred_task_wait_members WHERE scheduleId = ?")
46
+ .get(wait.scheduleId as string),
47
+ ).toEqual({
48
+ scheduleId: wait.scheduleId,
49
+ taskId,
50
+ created_at: "created",
51
+ updated_at: "updated",
52
+ created_by: "creator",
53
+ updated_by: "updater",
54
+ });
55
+ }
56
+ db.run("DELETE FROM scheduled_tasks WHERE id = 'pending'");
57
+ expect(
58
+ db.query("SELECT * FROM deferred_task_wait_members WHERE scheduleId = 'pending'").all(),
59
+ ).toEqual([]);
60
+ expect(db.query("PRAGMA foreign_key_check").all()).toEqual([]);
61
+ } finally {
62
+ db.close();
63
+ }
64
+ });