@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
@@ -1,562 +0,0 @@
1
- import {
2
- require_dist
3
- } from "./cli-qgm2pfpq.js";
4
- import {
5
- getAutomationSetupStates,
6
- getExecutorRegistry,
7
- handleScheduleTrigger,
8
- isNeedsSetupFailure,
9
- notifyAutomationPreflightFailure,
10
- preflightAutomation,
11
- recordSchedulePreflightFailure,
12
- renderAutomationTokens,
13
- schedulePreflightInput,
14
- startWorkflowExecution
15
- } from "./cli-ddfw1mc4.js";
16
- import {
17
- buildScriptCredentialBindings,
18
- getScript,
19
- getScriptApiConnectionDescriptors,
20
- getScriptMcpConnectionDescriptors,
21
- runScript
22
- } from "./cli-svbrpf5q.js";
23
- import {
24
- createTaskWithSiblingAwareness
25
- } from "./cli-ayvy5kde.js";
26
- import {
27
- ensure
28
- } from "./cli-3sysyjve.js";
29
- import {
30
- getDbClient,
31
- getDueScheduledTasks,
32
- getScheduledTaskById,
33
- getUserById,
34
- getWorkflow,
35
- getWorkflowRun,
36
- init_context_key,
37
- init_db,
38
- init_telemetry,
39
- scheduleContextKey,
40
- telemetry,
41
- updateScheduledTask
42
- } from "./cli-qgd4sqz5.js";
43
- import {
44
- init_event_bus,
45
- workflowEventBus
46
- } from "./cli-f7kvq46p.js";
47
- import {
48
- __toESM
49
- } from "./cli-bc05qbss.js";
50
-
51
- // src/scheduler/scheduler.ts
52
- var import_cron_parser = __toESM(require_dist(), 1);
53
- init_db();
54
- init_telemetry();
55
-
56
- // src/scheduler/deferred-task-waits.ts
57
- init_db();
58
- init_event_bus();
59
-
60
- // src/scheduler/schedule-task.ts
61
- init_db();
62
- init_context_key();
63
- async function createStandaloneScheduleTask(schedule, extraTags = []) {
64
- if (!schedule.taskTemplate) {
65
- throw new Error(`Schedule "${schedule.name}" has no taskTemplate (targetType=agent-task)`);
66
- }
67
- const task = await createTaskWithSiblingAwareness(schedule.taskTemplate, {
68
- key: schedule.key,
69
- creatorAgentId: schedule.createdByAgentId,
70
- taskType: schedule.taskType,
71
- tags: [...schedule.tags, "scheduled", `schedule:${schedule.name}`, ...extraTags],
72
- priority: schedule.priority,
73
- agentId: schedule.targetAgentId,
74
- routingReason: schedule.targetAgentId ? "human_pinned" : undefined,
75
- model: schedule.model,
76
- modelTier: schedule.modelTier,
77
- scheduleId: schedule.id,
78
- source: "schedule",
79
- requestedByUserId: schedule.createdBy,
80
- contextKey: scheduleContextKey({ scheduleId: schedule.id }),
81
- parentTaskId: schedule.parentTaskId
82
- });
83
- if (schedule.taskType === "deferred" && schedule.parentTaskId) {
84
- await getDbClient().run("UPDATE deferred_task_waits SET taskId = ?, updated_at = ? WHERE status = 'pending' AND taskId = ?", [task.id, new Date().toISOString(), schedule.parentTaskId]);
85
- }
86
- return task;
87
- }
88
-
89
- // src/scheduler/deferred-task-waits.ts
90
- async function dispatchDeferredTaskWait(scheduleId, reason, extraTags = []) {
91
- const client = getDbClient();
92
- if (!await client.get("SELECT * FROM deferred_task_waits WHERE scheduleId = ?", [
93
- scheduleId
94
- ]))
95
- return;
96
- return client.transaction(async () => {
97
- const wait = await client.get("SELECT * FROM deferred_task_waits WHERE scheduleId = ?", [scheduleId]);
98
- if (!wait || wait.status !== "pending")
99
- return {};
100
- if (reason !== "ceiling" && wait.eventName !== "settled" && wait.eventName !== reason)
101
- return {};
102
- let schedule = await getScheduledTaskById(scheduleId);
103
- if (!schedule?.enabled)
104
- return {};
105
- const now = new Date().toISOString();
106
- const claimed = await client.run("UPDATE deferred_task_waits SET status = 'fired', firedBy = ?, resolvedAt = ?, updated_at = ? WHERE scheduleId = ? AND status = 'pending'", [reason, now, now, scheduleId]);
107
- if (!claimed.changes)
108
- return {};
109
- if (schedule.createdBy && !await getUserById(schedule.createdBy)) {
110
- schedule = { ...schedule, createdBy: undefined };
111
- }
112
- if (!schedule.taskTemplate)
113
- throw new Error(`Schedule "${schedule.name}" has no taskTemplate`);
114
- const cause = reason === "ceiling" ? "ceiling expired" : `${reason} for task ${wait.taskId}`;
115
- const task = await createStandaloneScheduleTask({
116
- ...schedule,
117
- taskTemplate: `${schedule.taskTemplate}
118
-
119
- Wake-up cause: ${cause}.`
120
- }, extraTags);
121
- await client.run("UPDATE deferred_task_waits SET childTaskId = ? WHERE scheduleId = ?", [
122
- task.id,
123
- scheduleId
124
- ]);
125
- await updateScheduledTask(scheduleId, {
126
- enabled: false,
127
- nextRunAt: null,
128
- lastRunAt: now,
129
- lastUpdatedAt: now,
130
- consecutiveErrors: 0,
131
- lastErrorAt: null,
132
- lastErrorMessage: null
133
- });
134
- return { task };
135
- });
136
- }
137
- async function reconcileDeferredTaskWaits(taskId) {
138
- const rows = await getDbClient().query(`SELECT w.*, t.status AS taskStatus FROM deferred_task_waits w
139
- JOIN agent_tasks t ON t.id = w.taskId
140
- JOIN scheduled_tasks s ON s.id = w.scheduleId
141
- WHERE w.status = 'pending' AND s.enabled = 1 AND t.status IN ('completed', 'failed')
142
- AND NOT EXISTS (
143
- SELECT 1 FROM scheduled_tasks d
144
- WHERE d.parentTaskId = t.id AND d.taskType = 'deferred' AND d.enabled = 1
145
- )
146
- AND (w.eventName = 'settled' OR w.eventName = 'task.' || t.status)
147
- ${taskId ? "AND w.taskId = ?" : ""}`, taskId ? [taskId] : []);
148
- for (const row of rows) {
149
- try {
150
- await dispatchDeferredTaskWait(row.scheduleId, `task.${row.taskStatus}`);
151
- } catch (err) {
152
- console.error(`[Scheduler] Deferred task wake failed for ${row.scheduleId}:`, err);
153
- }
154
- }
155
- }
156
- function onTaskTerminal(payload) {
157
- if (!payload || typeof payload !== "object" || !("taskId" in payload) || typeof payload.taskId !== "string")
158
- return;
159
- reconcileDeferredTaskWaits(payload.taskId).catch((err) => {
160
- console.error("[Scheduler] Deferred task event wake failed:", err);
161
- });
162
- }
163
- async function initDeferredTaskWaits() {
164
- stopDeferredTaskWaits();
165
- workflowEventBus.on("task.completed", onTaskTerminal);
166
- workflowEventBus.on("task.failed", onTaskTerminal);
167
- await reconcileDeferredTaskWaits();
168
- }
169
- function stopDeferredTaskWaits() {
170
- workflowEventBus.off("task.completed", onTaskTerminal);
171
- workflowEventBus.off("task.failed", onTaskTerminal);
172
- }
173
-
174
- // src/scheduler/scheduler.ts
175
- var schedulerInterval = null;
176
- var isProcessing = false;
177
- var executorRegistry = null;
178
- function resolveExecutorRegistry() {
179
- if (executorRegistry)
180
- return executorRegistry;
181
- try {
182
- return getExecutorRegistry();
183
- } catch {
184
- return null;
185
- }
186
- }
187
- async function executeScheduleScript(schedule) {
188
- if (!schedule.scriptName) {
189
- throw new Error(`Schedule "${schedule.name}" has no scriptName (targetType=script)`);
190
- }
191
- const script = await getScript({ name: schedule.scriptName, scope: "global" });
192
- if (!script) {
193
- throw new Error(`Script '${schedule.scriptName}' not found`);
194
- }
195
- const agentId = schedule.createdByAgentId ?? "schedule";
196
- const output = await runScript({
197
- source: script.source,
198
- args: schedule.scriptArgs ?? {},
199
- fsMode: "none",
200
- agentId,
201
- egressSecrets: await buildScriptCredentialBindings({ agentId }),
202
- apiConnections: getScriptApiConnectionDescriptors({ agentId }),
203
- mcpConnections: getScriptMcpConnectionDescriptors({ agentId }),
204
- timeoutMs: 60000
205
- });
206
- if (output.exitCode !== 0 || output.error) {
207
- throw new Error(output.stderr || `Script '${schedule.scriptName}' exited with code ${output.exitCode}${output.error ? ` (${output.error})` : ""}`);
208
- }
209
- }
210
-
211
- class AutomationNeedsSetupError extends Error {
212
- failureReason;
213
- constructor(failureReason) {
214
- super(failureReason);
215
- this.failureReason = failureReason;
216
- this.name = "AutomationNeedsSetupError";
217
- }
218
- }
219
- async function withoutDeletedRequester(schedule) {
220
- if (!schedule.createdBy || await getUserById(schedule.createdBy))
221
- return schedule;
222
- return { ...schedule, createdBy: undefined };
223
- }
224
- function renderScheduledTaskParams(schedule) {
225
- return renderAutomationTokens(schedule, schedule.params ?? {});
226
- }
227
- async function dispatchScheduleTarget(schedule, extraTags = []) {
228
- const deferred = await dispatchDeferredTaskWait(schedule.id, "ceiling", extraTags);
229
- if (deferred)
230
- return { triggeredWorkflows: false, ...deferred };
231
- const preflight = preflightAutomation(schedulePreflightInput(schedule), await getAutomationSetupStates());
232
- if (preflight.state === "needs_setup") {
233
- const recorded = await recordSchedulePreflightFailure(schedule.id, preflight.failureReason);
234
- if (recorded)
235
- await notifyAutomationPreflightFailure(preflight);
236
- throw new AutomationNeedsSetupError(preflight.failureReason);
237
- }
238
- schedule = renderScheduledTaskParams(schedule);
239
- schedule = await withoutDeletedRequester(schedule);
240
- switch (schedule.targetType) {
241
- case "workflow": {
242
- if (!schedule.workflowId) {
243
- throw new Error(`Schedule "${schedule.name}" has no workflowId (targetType=workflow)`);
244
- }
245
- const workflow = await getWorkflow(schedule.workflowId);
246
- if (!workflow) {
247
- throw new Error(`Workflow ${schedule.workflowId} not found`);
248
- }
249
- if (!workflow.enabled) {
250
- throw new Error(`Workflow ${schedule.workflowId} is disabled`);
251
- }
252
- const registry = resolveExecutorRegistry();
253
- if (!registry) {
254
- throw new Error("Workflow engine not initialized — cannot dispatch schedule to workflow");
255
- }
256
- const triggerData = {
257
- scheduleId: schedule.id,
258
- scheduleName: schedule.name,
259
- firedAt: new Date().toISOString()
260
- };
261
- const runId = await startWorkflowExecution(workflow, triggerData, registry, {
262
- triggerType: "schedule",
263
- requestedByUserId: schedule.createdBy
264
- });
265
- await throwIfWorkflowNeedsSetup(schedule.id, [runId]);
266
- console.log(`[Scheduler] Schedule "${schedule.name}" → triggered workflow "${workflow.name}"`);
267
- return { triggeredWorkflows: true, workflowRunIds: [runId] };
268
- }
269
- case "script": {
270
- await executeScheduleScript(schedule);
271
- return { triggeredWorkflows: false };
272
- }
273
- default: {
274
- let triggeredWorkflows = false;
275
- let workflowRunIds;
276
- const registry = resolveExecutorRegistry();
277
- if (registry) {
278
- const runIds = await handleScheduleTrigger(schedule.id, schedule, registry);
279
- if (runIds.length > 0) {
280
- await throwIfWorkflowNeedsSetup(schedule.id, runIds);
281
- triggeredWorkflows = true;
282
- workflowRunIds = runIds;
283
- console.log(`[Scheduler] Schedule "${schedule.name}" → triggered ${runIds.length} workflow(s)`);
284
- }
285
- }
286
- if (!triggeredWorkflows) {
287
- const task = await getDbClient().transaction(async () => createStandaloneScheduleTask(schedule, extraTags));
288
- return { triggeredWorkflows, task };
289
- }
290
- return { triggeredWorkflows, workflowRunIds };
291
- }
292
- }
293
- }
294
- async function throwIfWorkflowNeedsSetup(scheduleId, runIds) {
295
- for (const runId of runIds) {
296
- const run = await getWorkflowRun(runId);
297
- if (!isNeedsSetupFailure(run?.error))
298
- continue;
299
- await recordSchedulePreflightFailure(scheduleId, run.error);
300
- throw new AutomationNeedsSetupError(run.error);
301
- }
302
- }
303
- async function advanceScheduleAfterNeedsSetup(schedule, now = new Date) {
304
- schedule = renderScheduledTaskParams(schedule);
305
- const timestamp = now.toISOString();
306
- if (schedule.scheduleType === "one_time") {
307
- await updateScheduledTask(schedule.id, {
308
- nextRunAt: null,
309
- lastUpdatedAt: timestamp
310
- });
311
- return;
312
- }
313
- await updateScheduledTask(schedule.id, {
314
- nextRunAt: calculateNextRun(schedule.timezone?.includes("{{") ? { ...schedule, timezone: "UTC" } : schedule, now),
315
- lastUpdatedAt: timestamp
316
- });
317
- }
318
- async function recoverMissedSchedules() {
319
- const now = new Date;
320
- const dueSchedules = await getDueScheduledTasks();
321
- for (const storedSchedule of dueSchedules) {
322
- const schedule = renderScheduledTaskParams(storedSchedule);
323
- if (!schedule.nextRunAt)
324
- continue;
325
- const missedBy = now.getTime() - new Date(schedule.nextRunAt).getTime();
326
- if (missedBy < 15000)
327
- continue;
328
- console.log(`[Scheduler] Recovering missed schedule "${schedule.name}" ` + `(was due ${Math.round(missedBy / 1000)}s ago)`);
329
- let triggeredWorkflows = false;
330
- try {
331
- ({ triggeredWorkflows } = await dispatchScheduleTarget(schedule, ["recovered"]));
332
- if (schedule.scheduleType === "one_time") {
333
- await updateScheduledTask(schedule.id, {
334
- lastRunAt: now.toISOString(),
335
- nextRunAt: null,
336
- enabled: false,
337
- lastUpdatedAt: now.toISOString()
338
- });
339
- } else {
340
- const nextRun = calculateNextRun(schedule, now);
341
- await updateScheduledTask(schedule.id, {
342
- lastRunAt: now.toISOString(),
343
- nextRunAt: nextRun,
344
- lastUpdatedAt: now.toISOString()
345
- });
346
- }
347
- if (schedule.scheduleType === "one_time") {
348
- console.log(`[Scheduler] One-time schedule "${schedule.name}" recovered and auto-disabled`);
349
- }
350
- telemetry.schedule("executed", {
351
- scheduleType: schedule.scheduleType,
352
- triggeredWorkflows,
353
- wasRecovered: true
354
- });
355
- } catch (err) {
356
- if (err instanceof AutomationNeedsSetupError) {
357
- await advanceScheduleAfterNeedsSetup(schedule, now);
358
- telemetry.schedule("error", {
359
- scheduleType: schedule.scheduleType,
360
- triggeredWorkflows,
361
- wasRecovered: true,
362
- consecutiveErrors: schedule.consecutiveErrors ?? 0
363
- });
364
- continue;
365
- }
366
- telemetry.schedule("error", {
367
- scheduleType: schedule.scheduleType,
368
- triggeredWorkflows,
369
- wasRecovered: true,
370
- consecutiveErrors: schedule.consecutiveErrors ?? 0
371
- });
372
- console.error(`[Scheduler] Error recovering "${schedule.name}":`, err);
373
- }
374
- }
375
- }
376
- function calculateNextRun(schedule, fromTime = new Date) {
377
- if (schedule.cronExpression) {
378
- const interval = import_cron_parser.CronExpressionParser.parse(schedule.cronExpression, {
379
- currentDate: fromTime,
380
- tz: schedule.timezone || "UTC"
381
- });
382
- const nextDate = interval.next();
383
- const isoString = nextDate.toISOString();
384
- if (!isoString) {
385
- throw new Error("Failed to calculate next run time from cron expression");
386
- }
387
- return isoString;
388
- }
389
- if (schedule.intervalMs) {
390
- return new Date(fromTime.getTime() + schedule.intervalMs).toISOString();
391
- }
392
- throw new Error("Schedule must have cronExpression or intervalMs");
393
- }
394
- var ERROR_BACKOFF_MS = [
395
- 60000,
396
- 300000,
397
- 900000,
398
- 1800000,
399
- 3600000
400
- ];
401
- var MAX_CONSECUTIVE_ERRORS = 5;
402
- function getBackoffMs(consecutiveErrors) {
403
- const idx = Math.min(consecutiveErrors - 1, ERROR_BACKOFF_MS.length - 1);
404
- return ERROR_BACKOFF_MS[Math.max(0, idx)] ?? ERROR_BACKOFF_MS[0];
405
- }
406
- async function executeSchedule(schedule) {
407
- schedule = renderScheduledTaskParams(schedule);
408
- let triggeredWorkflows = false;
409
- try {
410
- ({ triggeredWorkflows } = await dispatchScheduleTarget(schedule));
411
- const now = new Date().toISOString();
412
- if (schedule.scheduleType === "one_time") {
413
- await updateScheduledTask(schedule.id, {
414
- lastRunAt: now,
415
- nextRunAt: null,
416
- enabled: false,
417
- lastUpdatedAt: now,
418
- consecutiveErrors: 0,
419
- lastErrorAt: null,
420
- lastErrorMessage: null
421
- });
422
- console.log(`[Scheduler] Executed one-time schedule "${schedule.name}", auto-disabled`);
423
- } else {
424
- const nextRun = calculateNextRun(schedule, new Date);
425
- await updateScheduledTask(schedule.id, {
426
- lastRunAt: now,
427
- nextRunAt: nextRun,
428
- lastUpdatedAt: now,
429
- consecutiveErrors: 0,
430
- lastErrorAt: null,
431
- lastErrorMessage: null
432
- });
433
- console.log(`[Scheduler] Executed schedule "${schedule.name}", next run: ${nextRun}`);
434
- }
435
- telemetry.schedule("executed", {
436
- scheduleType: schedule.scheduleType,
437
- triggeredWorkflows,
438
- wasRecovered: false
439
- });
440
- } catch (err) {
441
- if (err instanceof AutomationNeedsSetupError) {
442
- await advanceScheduleAfterNeedsSetup(schedule);
443
- telemetry.schedule("error", {
444
- scheduleType: schedule.scheduleType,
445
- triggeredWorkflows,
446
- wasRecovered: false,
447
- consecutiveErrors: schedule.consecutiveErrors ?? 0
448
- });
449
- return;
450
- }
451
- const errorCount = (schedule.consecutiveErrors ?? 0) + 1;
452
- const now = new Date;
453
- const errorMsg = err instanceof Error ? err.message : String(err);
454
- console.error(`[Scheduler] Error executing "${schedule.name}" (${errorCount} consecutive):`, errorMsg);
455
- const updates = {
456
- consecutiveErrors: errorCount,
457
- lastErrorAt: now.toISOString(),
458
- lastErrorMessage: errorMsg.slice(0, 500),
459
- lastUpdatedAt: now.toISOString()
460
- };
461
- if (schedule.scheduleType === "one_time") {
462
- updates.enabled = false;
463
- console.warn(`[Scheduler] One-time schedule "${schedule.name}" failed, auto-disabled: ${errorMsg}`);
464
- } else if (errorCount >= MAX_CONSECUTIVE_ERRORS) {
465
- updates.enabled = false;
466
- console.warn(`[Scheduler] Auto-disabled "${schedule.name}" after ${errorCount} consecutive errors`);
467
- } else {
468
- const backoff = getBackoffMs(errorCount);
469
- updates.nextRunAt = new Date(now.getTime() + backoff).toISOString();
470
- console.log(`[Scheduler] Backing off "${schedule.name}" for ${backoff / 1000}s`);
471
- }
472
- await updateScheduledTask(schedule.id, updates);
473
- telemetry.schedule("error", {
474
- scheduleType: schedule.scheduleType,
475
- triggeredWorkflows,
476
- wasRecovered: false,
477
- consecutiveErrors: errorCount
478
- });
479
- }
480
- }
481
- function startScheduler(registry, intervalMs = 1e4, opts) {
482
- if (schedulerInterval) {
483
- console.log("[Scheduler] Already running");
484
- return;
485
- }
486
- executorRegistry = registry;
487
- console.log(`[Scheduler] Starting with ${intervalMs}ms polling interval`);
488
- initDeferredTaskWaits().then(() => recoverMissedSchedules()).then(() => processSchedules()).catch((err) => console.error("[Scheduler] Recovery failed:", err));
489
- schedulerInterval = setInterval(async () => {
490
- await processSchedules();
491
- }, intervalMs);
492
- ensure({
493
- id: "scheduler_started",
494
- flow: "api",
495
- runId: opts?.runId ?? "",
496
- depIds: ["listen"],
497
- data: {},
498
- filter: ({}, ctx) => {
499
- const start = ctx.deps.find((d) => d.id === "listen");
500
- return !!start && start.data?.capabilities?.includes("scheduling");
501
- },
502
- validator: ({}, ctx) => {
503
- const start = ctx.deps.find((d) => d.id === "listen");
504
- return !!start && start.data?.capabilities?.includes("scheduling");
505
- },
506
- conditions: [{ timeout_ms: 1e4 }]
507
- });
508
- }
509
- async function processSchedules() {
510
- if (isProcessing)
511
- return;
512
- isProcessing = true;
513
- try {
514
- await reconcileDeferredTaskWaits();
515
- const dueSchedules = await getDueScheduledTasks();
516
- for (const schedule of dueSchedules) {
517
- try {
518
- await executeSchedule(schedule);
519
- } catch (err) {
520
- console.error(`[Scheduler] Error executing "${schedule.name}":`, err);
521
- }
522
- }
523
- } finally {
524
- isProcessing = false;
525
- }
526
- }
527
- function stopScheduler() {
528
- stopDeferredTaskWaits();
529
- if (schedulerInterval) {
530
- clearInterval(schedulerInterval);
531
- schedulerInterval = null;
532
- isProcessing = false;
533
- console.log("[Scheduler] Stopped");
534
- }
535
- }
536
- async function runScheduleNow(scheduleId) {
537
- const schedule = await getScheduledTaskById(scheduleId);
538
- if (!schedule) {
539
- throw new Error(`Schedule not found: ${scheduleId}`);
540
- }
541
- if (!schedule.enabled) {
542
- throw new Error(`Schedule is disabled: ${schedule.name}`);
543
- }
544
- await dispatchScheduleTarget(schedule, ["manual-run"]);
545
- const now = new Date().toISOString();
546
- if (schedule.scheduleType === "one_time") {
547
- await updateScheduledTask(schedule.id, {
548
- lastRunAt: now,
549
- nextRunAt: null,
550
- enabled: false,
551
- lastUpdatedAt: now
552
- });
553
- console.log(`[Scheduler] Manually executed one-time schedule "${schedule.name}", auto-disabled`);
554
- } else {
555
- await updateScheduledTask(schedule.id, {
556
- lastRunAt: now,
557
- lastUpdatedAt: now
558
- });
559
- console.log(`[Scheduler] Manually executed schedule "${schedule.name}"`);
560
- }
561
- }
562
- export { reconcileDeferredTaskWaits, dispatchScheduleTarget, calculateNextRun, startScheduler, stopScheduler, runScheduleNow };