@desplega.ai/agent-swarm 1.173.0 → 2.0.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 (432) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-ccm9xrep.js → acp-adapter-sj2g0m84.js} +17 -16
  3. package/dist/{actions-sgeyv08k.js → actions-fegk44gr.js} +39 -34
  4. package/dist/{amp-adapter-gpxp3kc9.js → amp-adapter-ad8ft89x.js} +8 -7
  5. package/dist/{app-km9qnv2f.js → app-kfvgbvzy.js} +18 -14
  6. package/dist/{assistant-5r8tcvvd.js → assistant-z7zdy9ja.js} +40 -35
  7. package/dist/{boot-reembed-swwzdgd7.js → boot-reembed-5c2z0mbe.js} +10 -9
  8. package/dist/{boot-reembed-16rv9843.js → boot-reembed-j8xa181e.js} +10 -9
  9. package/dist/{boot-scrub-sweep-zkr6vkqb.js → boot-scrub-sweep-hnkn3rgt.js} +11 -10
  10. package/dist/{boot-seeds-d8sp49t2.js → boot-seeds-kwjq4d2z.js} +14 -13
  11. package/dist/{claude-adapter-yzzzh8jp.js → claude-adapter-9vmvpvgd.js} +19 -18
  12. package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-k9qae05j.js} +7 -5
  13. package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-q54zx5q2.js} +6 -4
  14. package/dist/{claude-sdk-session-4whxere4.js → claude-sdk-session-9jye6cxr.js} +11881 -11472
  15. package/dist/{cli-94b48jhk.js → cli-03gedhng.js} +16 -14
  16. package/dist/{cli-1w0vj3gw.js → cli-1e4b6bzh.js} +7 -7
  17. package/dist/{cli-d603qf86.js → cli-29jc5q7w.js} +10 -8
  18. package/dist/cli-2m1ktfzz.js +17795 -0
  19. package/dist/{cli-x119kdba.js → cli-3dj8k4vy.js} +1 -1
  20. package/dist/{cli-srqq3gc5.js → cli-3fbmmawm.js} +5 -5
  21. package/dist/{cli-gmdajfw5.js → cli-4jxm2qtz.js} +4987 -1708
  22. package/dist/{cli-tadfgd0t.js → cli-5hkm7whv.js} +33 -4
  23. package/dist/{cli-42qhyvwx.js → cli-5t4f29ez.js} +3 -3
  24. package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
  25. package/dist/cli-6cvfxs8r.js +47 -0
  26. package/dist/{cli-0kxf81jj.js → cli-6jyj59nb.js} +2 -2
  27. package/dist/{cli-w1apjecb.js → cli-6razj6t4.js} +2 -2
  28. package/dist/{cli-anzdk0z4.js → cli-74ahz61x.js} +2 -2
  29. package/dist/{cli-m89t9jdf.js → cli-7x0g4sn1.js} +15416 -16024
  30. package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
  31. package/dist/{cli-81r1wjyv.js → cli-9nfx44eh.js} +1 -1
  32. package/dist/cli-9traj3dn.js +638 -0
  33. package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
  34. package/dist/{cli-na2pxe4f.js → cli-apx87jne.js} +2 -2
  35. package/dist/{cli-rfz2ve55.js → cli-bzszjf2p.js} +2855 -862
  36. package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
  37. package/dist/{cli-hsem16hb.js → cli-cgtksawx.js} +7 -4
  38. package/dist/{cli-db3m6zdt.js → cli-d2qr7aj4.js} +1 -1
  39. package/dist/{cli-rfs4vddv.js → cli-d5f9ed5c.js} +5 -5
  40. package/dist/cli-e3g5mbkz.js +776 -0
  41. package/dist/{cli-7jykv7ef.js → cli-e6mpjhed.js} +1 -1
  42. package/dist/{cli-7a93cv8c.js → cli-ee9gtz70.js} +98 -23
  43. package/dist/{cli-3nxdmjrc.js → cli-eejsgvm4.js} +4 -4
  44. package/dist/{cli-fmhj1ehj.js → cli-ef1hg1wv.js} +470 -51
  45. package/dist/cli-f527ce74.js +781 -0
  46. package/dist/{cli-ppy4nnnh.js → cli-f7kr7svz.js} +2 -2
  47. package/dist/cli-hjwmhcg1.js +10622 -0
  48. package/dist/{cli-2bw3w47j.js → cli-hnhtk6cj.js} +1 -1
  49. package/dist/{cli-ywm1azg9.js → cli-hnmhtzvh.js} +6 -4
  50. package/dist/{cli-h7k0xtry.js → cli-hvqbtna4.js} +4 -1256
  51. package/dist/{cli-s8z6x4b4.js → cli-j0pfptdp.js} +218 -102
  52. package/dist/cli-jta2eyzc.js +619 -0
  53. package/dist/{cli-5er5gjbm.js → cli-k382tshb.js} +10 -11
  54. package/dist/{cli-v3zhnxsb.js → cli-k3dp5tpf.js} +2 -2
  55. package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
  56. package/dist/cli-kceah1eh.js +92 -0
  57. package/dist/{cli-ne7smj1b.js → cli-ke896fcf.js} +10 -10
  58. package/dist/{cli-xc7p7s3g.js → cli-kt6zqg0e.js} +6 -6
  59. package/dist/{cli-wrh08zjd.js → cli-m50t4309.js} +5 -18
  60. package/dist/cli-n2wq4j7m.js +6985 -0
  61. package/dist/{cli-bv2etw2y.js → cli-n3hzg89b.js} +46 -15
  62. package/dist/{cli-tmhsxhb8.js → cli-n5vwg842.js} +23 -6
  63. package/dist/{cli-qm1448f9.js → cli-ne236afy.js} +8 -8
  64. package/dist/{cli-d161g69q.js → cli-p1x85d2t.js} +50 -2
  65. package/dist/{cli-7pz3b7x5.js → cli-przpmdgr.js} +25 -0
  66. package/dist/{cli-0a7mm3zp.js → cli-q0ke1yww.js} +25 -21
  67. package/dist/{cli-e3pmyt39.js → cli-q50942rs.js} +1 -1
  68. package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
  69. package/dist/{cli-phcqp1b9.js → cli-r2pnvj8g.js} +2 -2
  70. package/dist/{cli-jpc4r224.js → cli-r62a35ea.js} +19 -3
  71. package/dist/{cli-cd0hv9nh.js → cli-ra0xzggj.js} +2 -2
  72. package/dist/cli-rhs9pz33.js +294 -0
  73. package/dist/{cli-r4fqfpwf.js → cli-s2sp957d.js} +50 -27
  74. package/dist/{cli-1x7da0de.js → cli-s4setq91.js} +8 -8
  75. package/dist/{cli-6thk4jz3.js → cli-se8w6wny.js} +6 -6
  76. package/dist/cli-skxvvpap.js +10140 -0
  77. package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
  78. package/dist/{cli-0p3enk35.js → cli-tqaazemc.js} +9 -1
  79. package/dist/{cli-nwrdx840.js → cli-tr4sxp68.js} +3 -3
  80. package/dist/{cli-r0byd61h.js → cli-tsde1hdr.js} +15 -15
  81. package/dist/{cli-b07hr3bt.js → cli-txqb9s38.js} +2 -2
  82. package/dist/{cli-6r2f7edk.js → cli-v1yb0rqb.js} +6 -6
  83. package/dist/{cli-saqyage0.js → cli-vatyhshy.js} +179 -27
  84. package/dist/{cli-5wpw4rab.js → cli-vdach5a9.js} +5 -5
  85. package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
  86. package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
  87. package/dist/{cli-c3rk1v0x.js → cli-wayw93nt.js} +3 -3
  88. package/dist/cli-wmgrkscj.js +23254 -0
  89. package/dist/{cli-9xf7fdtp.js → cli-z5jjpaxw.js} +29 -6
  90. package/dist/{cli-451ks6aw.js → cli-zkpks3r3.js} +1 -1
  91. package/dist/cli.js +29 -45
  92. package/dist/{codex-adapter-r3dn4fp5.js → codex-adapter-y81sssk0.js} +15 -14
  93. package/dist/{codex-login-841kv5fk.js → codex-login-f2rcfpp9.js} +3 -2
  94. package/dist/{codex-session-runner-fwt793h4.js → codex-session-runner-8vx4j6a9.js} +15 -14
  95. package/dist/{commands-z8fq9qna.js → commands-kcpvpcrr.js} +11 -10
  96. package/dist/{controller-hq5ggpcp.js → controller-ywrmt6yd.js} +5 -4
  97. package/dist/{controllers-connect-3mf2btyj.js → controllers-connect-kwpvj3rf.js} +42 -37
  98. package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-cehv1qns.js} +7 -6
  99. package/dist/{db-yyhqqrbf.js → db-k8ankj20.js} +12 -11
  100. package/dist/{db-qfpq4bt7.js → db-ww5d7jq3.js} +28 -9
  101. package/dist/{devin-adapter-xgtj680j.js → devin-adapter-x1022qb1.js} +3 -2
  102. package/dist/{dispatcher-x0x7qfcq.js → dispatcher-e8gq5m68.js} +38 -33
  103. package/dist/{docker-f503k9p0.js → docker-ff6y1190.js} +3 -2
  104. package/dist/{dsh-adapter-34etvb5m.js → dsh-adapter-3epjm3af.js} +7 -6
  105. package/dist/{e2b-66xra4az.js → e2b-8ygwhg0f.js} +4 -3
  106. package/dist/{e2b-xwhyj8cw.js → e2b-swhnpw3n.js} +4 -3
  107. package/dist/{event-bus-vjtv82gm.js → event-bus-6axnngdj.js} +3 -2
  108. package/dist/{external-channel-h1fjecwe.js → external-channel-h3359cwn.js} +11 -10
  109. package/dist/{google-generative-ai-szdxbpqg.js → google-generative-ai-g8db7x0f.js} +4 -2
  110. package/dist/{google-vertex-qzw3p36d.js → google-vertex-r2692q0r.js} +4 -2
  111. package/dist/{grok-adapter-e7mr287e.js → grok-adapter-0d4x7gkx.js} +18 -17
  112. package/dist/{handlers-znb9n7d4.js → handlers-an1gzv21.js} +41 -36
  113. package/dist/{heartbeat-bm4qkn8d.js → heartbeat-6dakeb61.js} +43 -38
  114. package/dist/{hook-254r4mza.js → hook-6v6cv6d5.js} +11 -23
  115. package/dist/{hook-xaa3q80s.js → hook-sa5xye4y.js} +12 -11
  116. package/dist/{http-3dgrgp8y.js → http-r7f3eky0.js} +1499 -251
  117. package/dist/index-52j1aja4.js +3465 -0
  118. package/dist/{index-fx3jqq1e.js → index-7ep4gzdk.js} +38 -33
  119. package/dist/index-9gw58n4k.js +193 -0
  120. package/dist/index-9j87mcm8.js +56305 -0
  121. package/dist/index-bsmcresk.js +79424 -0
  122. package/dist/index-mh85qhec.js +475 -0
  123. package/dist/{index-g2byveez.js → index-rmpw9a8q.js} +38 -33
  124. package/dist/{index-2ybk7khy.js → index-s2wxgzr0.js} +468 -683
  125. package/dist/{index-bdsqa799.js → index-v1v6n7hg.js} +43 -38
  126. package/dist/index-we27kd31.js +12810 -0
  127. package/dist/{index-jd7sejm2.js → index-zk96aq1k.js} +10 -9
  128. package/dist/{keepalive-6ywhpja1.js → keepalive-be9vwy5h.js} +12 -11
  129. package/dist/{lead-cw45n21s.js → lead-0861cwrf.js} +61 -56
  130. package/dist/{maintenance-ss1a1ge9.js → maintenance-mzzgc8bn.js} +10 -9
  131. package/dist/{node-fkajaq96.js → node-mn1zs7an.js} +2 -1
  132. package/dist/{oauth-refresh-sweep-3c6f8vyy.js → oauth-refresh-sweep-cpdnfwdj.js} +11 -10
  133. package/dist/{onboard-8hzdhc1k.js → onboard-fh8qs4r3.js} +11 -3
  134. package/dist/{opencode-adapter-qbchbcfz.js → opencode-adapter-nm42wwj8.js} +18 -13
  135. package/dist/{otel-impl-e6mnvc4v.js → otel-impl-x6c1c9g4.js} +242 -868
  136. package/dist/{pi-mono-adapter-3c9g9snh.js → pi-mono-adapter-9n2ya240.js} +244 -106
  137. package/dist/{pricing-refresh-gedkjdw0.js → pricing-refresh-qb0rv0ap.js} +12 -11
  138. package/dist/{rbac-roles-dt4vh1yy.js → rbac-roles-1gzdwbh1.js} +11 -10
  139. package/dist/{rbac-roles-eszdg6pm.js → rbac-roles-3mraey52.js} +12 -11
  140. package/dist/{render-v2-907cy6sa.js → render-v2-agpa45zz.js} +18 -14
  141. package/dist/{resume-42stcaz0.js → resume-x0ydy9s9.js} +25 -21
  142. package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
  143. package/dist/{setup-adbc1c10.js → setup-as9ga0d6.js} +2 -2
  144. package/dist/{virtual-modules-rtmt494q.js → virtual-modules-9gkxqrap.js} +6 -5
  145. package/dist/{work-objects-wpj8ck95.js → work-objects-y5g1y7ev.js} +41 -36
  146. package/dist/{worker-bzdra9rf.js → worker-860c3e38.js} +61 -56
  147. package/dist/{x-qfmygqqv.js → x-m477fr0h.js} +3 -2
  148. package/openapi.json +523 -344
  149. package/package.json +10 -11
  150. package/src/be/config-refs.ts +60 -0
  151. package/src/be/db/page-versions.ts +15 -0
  152. package/src/be/db/runtime.ts +35 -8
  153. package/src/be/db/skill-name-resolution.ts +36 -0
  154. package/src/be/db/tasks/read.ts +230 -0
  155. package/src/be/db/tasks/write.ts +7 -0
  156. package/src/be/db.ts +52 -7
  157. package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
  158. package/src/be/migrations/216_task_resolved_effort.sql +5 -0
  159. package/src/be/migrations/217_chat_sdk_state.sql +104 -0
  160. package/src/be/model-catalog-store.ts +5 -1
  161. package/src/be/model-tier-resolution.ts +12 -1
  162. package/src/be/model-validation.ts +5 -2
  163. package/src/be/models-catalog.ts +26 -1
  164. package/src/be/modelsdev-cache.json +198 -63
  165. package/src/be/modelsdev-cache.ts +9 -1
  166. package/src/be/script-credential-broker.ts +39 -2
  167. package/src/be/scripts/run-saved.ts +1 -0
  168. package/src/be/scripts/typecheck.ts +10 -8
  169. package/src/be/seed/runner.ts +13 -1
  170. package/src/be/seed/state-db.ts +5 -0
  171. package/src/be/seed/types.ts +6 -0
  172. package/src/be/seed-pricing.ts +19 -2
  173. package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
  174. package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
  175. package/src/be/seed-skills/bundled-files.generated.json +0 -18
  176. package/src/be/seed-skills/index.ts +104 -3
  177. package/src/be/swarm-config-guard.ts +52 -0
  178. package/src/cli.tsx +0 -16
  179. package/src/commands/onboard/non-interactive.ts +4 -2
  180. package/src/commands/provider-credentials.ts +52 -6
  181. package/src/commands/runner.ts +190 -54
  182. package/src/e2b/env.ts +5 -0
  183. package/src/extensions/contract-types.generated.ts +1 -1
  184. package/src/extensions/contract.ts +45 -0
  185. package/src/extensions/dispatcher.ts +7 -0
  186. package/src/extensions/post-bridge.ts +40 -0
  187. package/src/github/handlers.ts +11 -4
  188. package/src/heartbeat/templates.ts +8 -5
  189. package/src/hooks/hook.ts +0 -26
  190. package/src/http/all-routes.ts +0 -1
  191. package/src/http/config.ts +36 -17
  192. package/src/http/core.ts +4 -0
  193. package/src/http/index.ts +14 -2
  194. package/src/http/integrations.ts +88 -1
  195. package/src/http/mcp.ts +15 -5
  196. package/src/http/page-proxy.ts +2 -4
  197. package/src/http/pages-public.ts +3 -3
  198. package/src/http/pages.ts +3 -13
  199. package/src/http/poll.ts +28 -68
  200. package/src/http/requested-by.ts +54 -0
  201. package/src/http/scripts.ts +1 -0
  202. package/src/http/stats.ts +1 -30
  203. package/src/http/tasks.ts +61 -5
  204. package/src/http/utils.ts +14 -0
  205. package/src/http/webhooks.ts +159 -1
  206. package/src/http/x.ts +1 -0
  207. package/src/integrations/chat-sdk/adapters.ts +129 -0
  208. package/src/integrations/chat-sdk/attachments.ts +232 -0
  209. package/src/integrations/chat-sdk/background.ts +36 -0
  210. package/src/integrations/chat-sdk/commands.ts +194 -0
  211. package/src/integrations/chat-sdk/config.ts +198 -0
  212. package/src/integrations/chat-sdk/discord-api.ts +63 -0
  213. package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
  214. package/src/integrations/chat-sdk/handlers.ts +28 -0
  215. package/src/integrations/chat-sdk/inbound.ts +426 -0
  216. package/src/integrations/chat-sdk/limits.ts +48 -0
  217. package/src/integrations/chat-sdk/logger.ts +81 -0
  218. package/src/integrations/chat-sdk/outbound.ts +123 -0
  219. package/src/integrations/chat-sdk/relay.ts +172 -0
  220. package/src/integrations/chat-sdk/router.ts +169 -0
  221. package/src/integrations/chat-sdk/runtime.ts +351 -0
  222. package/src/integrations/chat-sdk/schema.ts +245 -0
  223. package/src/integrations/chat-sdk/state.ts +243 -0
  224. package/src/integrations/chat-sdk/status.ts +244 -0
  225. package/src/integrations/chat-sdk/steering.ts +58 -0
  226. package/src/integrations/chat-sdk/teams-origin.ts +77 -0
  227. package/src/integrations/chat-sdk/telegram-api.ts +56 -0
  228. package/src/integrations/chat-sdk/templates.ts +16 -0
  229. package/src/integrations/chat-sdk/test-hooks.ts +37 -0
  230. package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
  231. package/src/integrations/chat-sdk/typing.ts +65 -0
  232. package/src/pages/version.ts +4 -5
  233. package/src/prompts/base-prompt.ts +111 -45
  234. package/src/providers/acp-target-catalog.ts +6 -0
  235. package/src/providers/acp-targets.ts +55 -2
  236. package/src/providers/amp-adapter.ts +1 -1
  237. package/src/providers/claude-adapter.ts +1 -1
  238. package/src/providers/claude-flag-settings.ts +17 -5
  239. package/src/providers/claude-managed-adapter.ts +1 -1
  240. package/src/providers/claude-session-events.ts +6 -1
  241. package/src/providers/dsh-adapter.ts +1 -1
  242. package/src/providers/opencode-adapter.ts +243 -26
  243. package/src/providers/opencode-swarm-plugin.ts +31 -0
  244. package/src/providers/pi-mono-adapter.ts +398 -153
  245. package/src/providers/pricing-sources.md +33 -2
  246. package/src/providers/reasoning-effort.ts +27 -0
  247. package/src/providers/types.ts +6 -2
  248. package/src/rbac/legacy-policy.ts +8 -2
  249. package/src/rbac/permissions.ts +21 -0
  250. package/src/scheduler/scheduler.ts +4 -2
  251. package/src/scripts-runtime/loader.ts +19 -7
  252. package/src/scripts-runtime/sdk-allowlist.ts +8 -6
  253. package/src/scripts-runtime/swarm-sdk.ts +0 -11
  254. package/src/scripts-runtime/types/stdlib.d.ts +27 -15
  255. package/src/scripts-runtime/types/swarm-extension.d.ts +63 -1
  256. package/src/scripts-runtime/types/swarm-sdk.d.ts +27 -15
  257. package/src/server.ts +52 -18
  258. package/src/slack/event-dedup.ts +1 -1
  259. package/src/tasks/additive-buffer.ts +4 -2
  260. package/src/tasks/context-key.ts +60 -1
  261. package/src/tasks/model-pin.ts +67 -0
  262. package/src/tasks/worker-follow-up.ts +4 -31
  263. package/src/tests/acp-adapter.test.ts +42 -0
  264. package/src/tests/api-drain-worker-e2e.test.ts +1 -6
  265. package/src/tests/base-prompt.test.ts +58 -54
  266. package/src/tests/chat-sdk-commands.test.ts +191 -0
  267. package/src/tests/chat-sdk-config.test.ts +334 -0
  268. package/src/tests/chat-sdk-discord-api.test.ts +68 -0
  269. package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
  270. package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
  271. package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
  272. package/src/tests/chat-sdk-harness.ts +146 -0
  273. package/src/tests/chat-sdk-inbound.test.ts +363 -0
  274. package/src/tests/chat-sdk-relay.test.ts +470 -0
  275. package/src/tests/chat-sdk-reload.test.ts +128 -0
  276. package/src/tests/chat-sdk-shutdown.test.ts +220 -0
  277. package/src/tests/chat-sdk-slack.test.ts +268 -0
  278. package/src/tests/chat-sdk-state.test.ts +163 -0
  279. package/src/tests/chat-sdk-status-route.test.ts +382 -0
  280. package/src/tests/chat-sdk-teams.test.ts +277 -0
  281. package/src/tests/chat-sdk-tools.test.ts +520 -0
  282. package/src/tests/chat-sdk-typing.test.ts +120 -0
  283. package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
  284. package/src/tests/claude-adapter-binary.test.ts +9 -4
  285. package/src/tests/claude-flag-settings.test.ts +11 -3
  286. package/src/tests/claude-managed-adapter.test.ts +1 -1
  287. package/src/tests/claude-sdk-lifecycle.test.ts +9 -3
  288. package/src/tests/claude-thinking-tokens.test.ts +57 -0
  289. package/src/tests/claude-worker-parity.test.ts +2 -7
  290. package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
  291. package/src/tests/config-refs.test.ts +66 -0
  292. package/src/tests/context-key.test.ts +19 -0
  293. package/src/tests/cors-allowlist.test.ts +25 -0
  294. package/src/tests/create-page-tool.test.ts +18 -0
  295. package/src/tests/credential-check.test.ts +139 -0
  296. package/src/tests/credentials.test.ts +21 -0
  297. package/src/tests/db-runtime.test.ts +61 -0
  298. package/src/tests/db-task-read-contract.test.ts +20 -0
  299. package/src/tests/db-task-write-contract.test.ts +10 -0
  300. package/src/tests/docs-index-footprint.test.js +3 -3
  301. package/src/tests/dsh-adapter.test.ts +1 -1
  302. package/src/tests/enabled-capabilities.test.ts +20 -0
  303. package/src/tests/entrypoint-api-readiness.test.ts +14 -8
  304. package/src/tests/entrypoint-config-env-export.test.ts +5 -2
  305. package/src/tests/entrypoint-export-to-env.test.ts +78 -0
  306. package/src/tests/explicit-model-validation.test.ts +105 -1
  307. package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
  308. package/src/tests/extensions-post-bridge.test.ts +51 -0
  309. package/src/tests/fetch-resolved-env.test.ts +128 -0
  310. package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
  311. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
  312. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
  313. package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
  314. package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
  315. package/src/tests/github-handlers.test.ts +35 -0
  316. package/src/tests/harness-provider-resolution.test.ts +12 -0
  317. package/src/tests/heartbeat-checklist.test.ts +3 -2
  318. package/src/tests/hook-runtime-close.test.ts +0 -2
  319. package/src/tests/http-api-integration.test.ts +0 -25
  320. package/src/tests/migration-046-budgets.test.ts +17 -16
  321. package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
  322. package/src/tests/model-tier-resolution.test.ts +93 -0
  323. package/src/tests/models-catalog.test.ts +42 -1
  324. package/src/tests/openai-compatible-providers.test.ts +134 -0
  325. package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
  326. package/src/tests/opencode-adapter.test.ts +216 -2
  327. package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
  328. package/src/tests/opencode-shell-env.test.ts +145 -0
  329. package/src/tests/openrouter-base-url.test.ts +101 -151
  330. package/src/tests/page-proxy.test.ts +1 -1
  331. package/src/tests/pages-browser-sdk.test.ts +76 -0
  332. package/src/tests/pages-feedback.test.ts +1 -1
  333. package/src/tests/paused-tasks-requested-by.test.ts +102 -0
  334. package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
  335. package/src/tests/pi-mono-adapter.test.ts +385 -5
  336. package/src/tests/pi-shell-env.test.ts +170 -0
  337. package/src/tests/prompt-template-remaining.test.ts +35 -0
  338. package/src/tests/rbac-engine.test.ts +11 -3
  339. package/src/tests/runner-exit-after-tasks.test.ts +0 -4
  340. package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
  341. package/src/tests/script-connections.test.ts +2 -0
  342. package/src/tests/scripts-http.test.ts +201 -1
  343. package/src/tests/scripts-only-gating.test.ts +2 -3
  344. package/src/tests/scripts-runtime.test.ts +58 -40
  345. package/src/tests/secret-scrubber.test.ts +86 -0
  346. package/src/tests/seed-skills-bundled-files.test.ts +45 -53
  347. package/src/tests/seed-skills-retire.test.ts +182 -0
  348. package/src/tests/send-task-requester-gate.test.ts +58 -0
  349. package/src/tests/session-cost-recompute-unit.test.ts +46 -0
  350. package/src/tests/skill-get-name-resolution.test.ts +137 -0
  351. package/src/tests/sonnet-5-5-registry.test.ts +9 -1
  352. package/src/tests/swarm-config-export-to-env.test.ts +267 -0
  353. package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
  354. package/src/tests/swarm-diff.test.ts +1 -1
  355. package/src/tests/task-model-effort-rerun.test.ts +164 -0
  356. package/src/tests/task-session-prompts.test.ts +132 -0
  357. package/src/tests/task-tool-manifest.test.ts +14 -0
  358. package/src/tests/task-tools-ctx.test.ts +2 -0
  359. package/src/tests/tool-annotations.test.ts +6 -6
  360. package/src/tests/ui-logs-parser.test.ts +43 -0
  361. package/src/tests/used-by-route.test.ts +6 -0
  362. package/src/tests/vercel-ai-gateway.test.ts +149 -0
  363. package/src/tests/workflow-swarm-script.test.ts +38 -0
  364. package/src/tests/workflow-wait-filter.test.ts +5 -3
  365. package/src/tools/chat-access.ts +41 -0
  366. package/src/tools/chat-open-dm.ts +59 -0
  367. package/src/tools/chat-post.ts +74 -0
  368. package/src/tools/chat-read-thread.ts +100 -0
  369. package/src/tools/chat-reply.ts +75 -0
  370. package/src/tools/create-page.ts +3 -13
  371. package/src/tools/model-catalog/index.ts +2 -1
  372. package/src/tools/register-chat-channel.ts +139 -0
  373. package/src/tools/send-task.ts +24 -0
  374. package/src/tools/skills/skill-get.ts +17 -9
  375. package/src/tools/swarm-config/get-config.ts +2 -1
  376. package/src/tools/swarm-config/list-config.ts +2 -1
  377. package/src/tools/swarm-config/set-config.ts +16 -3
  378. package/src/tools/tool-config.ts +8 -6
  379. package/src/types.ts +12 -2
  380. package/src/utils/config-env-export.ts +74 -0
  381. package/src/utils/credentials.test.ts +92 -0
  382. package/src/utils/credentials.ts +52 -4
  383. package/src/utils/harness-provider.ts +15 -6
  384. package/src/utils/runtime-model-catalog.ts +11 -1
  385. package/src/utils/secret-scrubber.ts +71 -2
  386. package/src/utils/task-tool-manifest.ts +19 -2
  387. package/src/workflows/executors/swarm-script.ts +1 -0
  388. package/templates/skills/agent-browser/SKILL.md +1 -1
  389. package/templates/skills/agent-browser/content.md +1 -1
  390. package/templates/skills/apps/SKILL.md +8 -1
  391. package/templates/skills/apps/content.md +8 -1
  392. package/templates/skills/chat-sdk/config.json +14 -0
  393. package/templates/skills/chat-sdk/content.md +84 -0
  394. package/templates/skills/composio-gmail/content.md +7 -0
  395. package/templates/skills/composio-google-docs/content.md +1 -1
  396. package/templates/skills/email-domain-health/config.json +14 -0
  397. package/templates/skills/email-domain-health/content.md +131 -0
  398. package/templates/skills/kv-storage/content.md +2 -2
  399. package/templates/skills/pages/content.md +8 -10
  400. package/templates/skills/swarm-extensions/content.md +2 -0
  401. package/templates/skills/swarm-scripts/SKILL.md +4 -2
  402. package/templates/skills/swarm-scripts/config.json +1 -1
  403. package/templates/skills/swarm-scripts/content.md +4 -2
  404. package/templates/skills/workflow-iterate/content.md +38 -0
  405. package/dist/artifact-eczsknc3.js +0 -3843
  406. package/dist/cli-bd957dgb.js +0 -153
  407. package/dist/cli-q51yprfq.js +0 -1104
  408. package/dist/cli-t1ze64h3.js +0 -811
  409. package/dist/cli-tcc4wd5d.js +0 -56471
  410. package/dist/index-9ch1n761.js +0 -1102
  411. package/src/artifact-sdk/index.ts +0 -2
  412. package/src/artifact-sdk/localtunnel.d.ts +0 -20
  413. package/src/artifact-sdk/port.ts +0 -12
  414. package/src/artifact-sdk/server.ts +0 -183
  415. package/src/artifact-sdk/tunnel.ts +0 -19
  416. package/src/commands/artifact.ts +0 -249
  417. package/src/http/ecosystem.ts +0 -77
  418. package/src/tests/artifact-commands.test.ts +0 -92
  419. package/src/tests/artifact-sdk.test.ts +0 -793
  420. package/src/tests/register-service-security.test.ts +0 -194
  421. package/src/tools/list-services.ts +0 -107
  422. package/src/tools/register-service.ts +0 -177
  423. package/src/tools/unregister-service.ts +0 -73
  424. package/src/tools/update-service-status.ts +0 -96
  425. package/templates/skills/artifacts/config.json +0 -14
  426. package/templates/skills/artifacts/content.md +0 -344
  427. package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
  428. package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
  429. package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
  430. package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
  431. /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
  432. /package/src/{artifact-sdk → pages}/feedback-overlay.ts +0 -0
@@ -1,7 +1,3 @@
1
- import {
2
- BROWSER_SDK_JS,
3
- SWARM_UI_JS
4
- } from "./cli-t1ze64h3.js";
5
1
  import {
6
2
  SIMILARITY_THRESHOLD,
7
3
  isLeadChannelMonitoringEnabled,
@@ -11,7 +7,7 @@ import {
11
7
  } from "./cli-hz99wfxp.js";
12
8
  import {
13
9
  ACP_TARGET_IDS
14
- } from "./cli-7a0sde2x.js";
10
+ } from "./cli-6cagzc96.js";
15
11
  import {
16
12
  isCodexOAuthConfigKey
17
13
  } from "./cli-bqjfjex4.js";
@@ -24,11 +20,11 @@ import {
24
20
  } from "./cli-2pdaysab.js";
25
21
  import {
26
22
  reasoningCapability
27
- } from "./cli-tmhsxhb8.js";
23
+ } from "./cli-n5vwg842.js";
28
24
  import {
29
25
  ensureAgentFsCredentialsForAgent,
30
26
  inviteEmailToSharedOrg
31
- } from "./cli-phcqp1b9.js";
27
+ } from "./cli-r2pnvj8g.js";
32
28
  import"./cli-6zx22mv6.js";
33
29
  import {
34
30
  DEFAULT_CONNECTOR_CODE_LABEL,
@@ -39,16 +35,17 @@ import {
39
35
  startPoolRouting,
40
36
  stopHeartbeat,
41
37
  stopPoolRouting
42
- } from "./cli-r0byd61h.js";
38
+ } from "./cli-tsde1hdr.js";
43
39
  import {
44
40
  Anthropic
45
- } from "./cli-gmdajfw5.js";
41
+ } from "./cli-4jxm2qtz.js";
46
42
  import {
47
43
  runtimeSupervisorStatus,
48
44
  startRuntimeSupervisor,
49
45
  stopRuntimeSupervisor
50
- } from "./cli-ne7smj1b.js";
51
- import"./cli-ppy4nnnh.js";
46
+ } from "./cli-ke896fcf.js";
47
+ import"./cli-f7kr7svz.js";
48
+ import"./cli-knd276ed.js";
52
49
  import {
53
50
  AGENT_MAX_TASKS_CONFIG_KEY,
54
51
  ALL_CAPABILITIES,
@@ -75,6 +72,7 @@ import {
75
72
  SDK_ALLOWLIST,
76
73
  SUPPORTED_PROTOCOL_VERSIONS,
77
74
  TaskCreationBlockedError,
75
+ TelegramBotApiError,
78
76
  WebhookError,
79
77
  activateVersion,
80
78
  agentRanModel,
@@ -88,6 +86,7 @@ import {
88
86
  authorizeAssetKeyWrite,
89
87
  authorizeRoomNamespace,
90
88
  calculateNextRun,
89
+ callTelegramBotApi,
91
90
  canClaim,
92
91
  canReadMemory,
93
92
  cancelApprovalRequest,
@@ -124,6 +123,7 @@ import {
124
123
  enforceContentLengthCap,
125
124
  enqueueAdmissionRow,
126
125
  enqueueAuditRow,
126
+ errorMessage,
127
127
  estimateTokens,
128
128
  executeRawLlm,
129
129
  executeReadOnlyQuery,
@@ -133,6 +133,9 @@ import {
133
133
  extractAndVerifyCookie,
134
134
  flushAuditBuffer,
135
135
  getAgentHarnessCliVersion,
136
+ getChatInstance,
137
+ getChatSdkConfig,
138
+ getChatSdkHealth,
136
139
  getCombConfig,
137
140
  getEnabledCapabilities,
138
141
  getEventCountsFiltered,
@@ -147,6 +150,7 @@ import {
147
150
  getLinksForMemory,
148
151
  getMemoryChunks,
149
152
  getOAuthPreset,
153
+ getPageEditCounter,
150
154
  getPathSegments,
151
155
  getPosteriorsByIds,
152
156
  getRoom,
@@ -207,6 +211,9 @@ import {
207
211
  isAgentMailEnabled,
208
212
  isApiDraining,
209
213
  isAzureDevOpsEnabled,
214
+ isChatAdapterConfigured,
215
+ isChatSdkEnabled,
216
+ isChatSdkStopping,
210
217
  isGitHubEnabled,
211
218
  isGitLabEnabled,
212
219
  isInboxAllowed,
@@ -218,6 +225,7 @@ import {
218
225
  isLinearEnabled,
219
226
  isOriginAllowedForCredentials,
220
227
  isSenderAllowed,
228
+ isTrustedTeamsServiceUrl,
221
229
  issuePageSessionCookie,
222
230
  json,
223
231
  jsonError,
@@ -241,7 +249,6 @@ import {
241
249
  parseCookieHeader,
242
250
  parseModelTierOverridesHeader,
243
251
  parseQueryParams,
244
- parseSkillContent,
245
252
  patchWorkflowDefinition,
246
253
  poolTaskRunsOnHarness,
247
254
  posteriorMean,
@@ -267,6 +274,7 @@ import {
267
274
  reservedRoomKeyError,
268
275
  resetAgentMaxTasksMirror,
269
276
  resetRoom,
277
+ resolveAdapterApiUrl,
270
278
  resolveHttpAuditUserId,
271
279
  resolveHttpFavoriteOwner,
272
280
  resolveHttpRequestAuth,
@@ -301,17 +309,21 @@ import {
301
309
  snapshotPage,
302
310
  startAuditGc,
303
311
  startAuditWriter,
312
+ startChatSdk,
304
313
  steerTaskHandler,
305
314
  steerTaskOutputSchema,
306
315
  steerTaskUserInputSchema,
307
316
  stopAuditGc,
308
317
  stopAuditWriter,
318
+ stopChatSdk,
309
319
  stopExtensionRuntime,
310
320
  stripSiblingBlock,
311
321
  sweepRooms,
312
322
  syncTelemetryEnabled,
323
+ taskModelPin,
313
324
  toolErr,
314
325
  touchRuntimeInstance,
326
+ trackBackground,
315
327
  triggerSchemaErrorResponse,
316
328
  uninstallExtension,
317
329
  updateExtensionMeta,
@@ -332,13 +344,13 @@ import {
332
344
  wireHttpSpanLifecycle,
333
345
  workflowModelErrors,
334
346
  writeUnhandledError
335
- } from "./cli-rfz2ve55.js";
336
- import"./cli-451ks6aw.js";
347
+ } from "./cli-bzszjf2p.js";
348
+ import"./cli-zkpks3r3.js";
337
349
  import {
338
350
  AMP_ESTIMATE_MODELS,
339
351
  ampBillsCacheWrites,
340
352
  resolveAmpModel
341
- } from "./cli-2bw3w47j.js";
353
+ } from "./cli-hnhtk6cj.js";
342
354
  import {
343
355
  RATING_MODEL_MAX_LENGTH,
344
356
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -347,16 +359,12 @@ import {
347
359
  import {
348
360
  isMultiRuntimeEnabled
349
361
  } from "./cli-re8z5p8p.js";
350
- import"./cli-42qhyvwx.js";
351
362
  import {
352
363
  deleteModelCatalogOverlay,
353
364
  loadModelsCatalog,
354
365
  requestModelCatalogRefresh,
355
366
  upsertModelCatalogOverlay
356
- } from "./cli-9xf7fdtp.js";
357
- import {
358
- normalizeModelKey
359
- } from "./cli-jpc4r224.js";
367
+ } from "./cli-z5jjpaxw.js";
360
368
  import {
361
369
  ConnectionAuthInputSchema,
362
370
  MAX_SCRIPT_WALL_CLOCK_MS,
@@ -411,6 +419,7 @@ import {
411
419
  mcpOAuthSsrfOptions,
412
420
  normalizeTokenEndpointAuthMethod,
413
421
  oauthAppToProviderConfig,
422
+ parseSkillContent,
414
423
  publicEndpointSsrfOptions,
415
424
  readStreamCapped,
416
425
  refreshMcpToken,
@@ -434,7 +443,7 @@ import {
434
443
  upsertCredentialBinding,
435
444
  upsertMcpOAuthToken,
436
445
  upsertScriptConnection
437
- } from "./cli-7a93cv8c.js";
446
+ } from "./cli-ee9gtz70.js";
438
447
  import"./cli-epan13p1.js";
439
448
  import {
440
449
  detachedProcessGroup,
@@ -449,7 +458,12 @@ import {
449
458
  forceRefreshAuthorizationOrThrow,
450
459
  forceRefreshTokenOrThrow,
451
460
  oauthAppRowToProviderConfig
452
- } from "./cli-w1apjecb.js";
461
+ } from "./cli-6razj6t4.js";
462
+ import"./cli-5t4f29ez.js";
463
+ import {
464
+ normalizeModelKey
465
+ } from "./cli-r62a35ea.js";
466
+ import"./cli-6cvfxs8r.js";
453
467
  import {
454
468
  AgentFsProvider,
455
469
  FilesError,
@@ -468,14 +482,14 @@ import {
468
482
  startWorkflowExecution,
469
483
  validateJsonSchema,
470
484
  workflowSaveWarnings
471
- } from "./cli-1w0vj3gw.js";
485
+ } from "./cli-1e4b6bzh.js";
472
486
  import {
473
487
  createApprovalFollowUpTask,
474
488
  definitionNodeIds,
475
489
  generateEdges,
476
490
  validateDefinition
477
- } from "./cli-6r2f7edk.js";
478
- import"./cli-6thk4jz3.js";
491
+ } from "./cli-v1yb0rqb.js";
492
+ import"./cli-se8w6wny.js";
479
493
  import {
480
494
  CLIENT_ID,
481
495
  MAX_CODEX_OAUTH_SLOT,
@@ -486,10 +500,10 @@ import {
486
500
  getAccountId,
487
501
  getValidCodexOAuth,
488
502
  loadAllCodexOAuthSlots
489
- } from "./cli-7jykv7ef.js";
490
- import"./cli-b07hr3bt.js";
491
- import"./cli-h6vtvt5c.js";
503
+ } from "./cli-e6mpjhed.js";
492
504
  import"./cli-2x0e561b.js";
505
+ import"./cli-txqb9s38.js";
506
+ import"./cli-h6vtvt5c.js";
493
507
  import"./cli-fad8m16k.js";
494
508
  import"./cli-bsakbbkm.js";
495
509
  import"./cli-zxg80zs9.js";
@@ -509,18 +523,22 @@ import {
509
523
  recordDbRetentionStatement,
510
524
  recordDbRetentionSweep,
511
525
  recordSessionCost,
512
- require_content_type,
513
526
  startSlackApp,
514
527
  startSpan,
515
528
  stopSlackApp,
516
529
  withRemoteContext,
517
530
  withSpan,
518
531
  withSpanContext
519
- } from "./cli-tcc4wd5d.js";
520
- import"./cli-q51yprfq.js";
532
+ } from "./cli-skxvvpap.js";
533
+ import"./cli-n2wq4j7m.js";
534
+ import {
535
+ require_content_type
536
+ } from "./cli-wmgrkscj.js";
521
537
  import"./cli-3er6gcsn.js";
522
- import"./cli-yatxqynm.js";
523
- import"./cli-v3zhnxsb.js";
538
+ import"./cli-hjwmhcg1.js";
539
+ import"./cli-rhs9pz33.js";
540
+ import"./cli-9ha6hs2d.js";
541
+ import"./cli-k3dp5tpf.js";
524
542
  import {
525
543
  InvalidRuntimeTokenError,
526
544
  RuntimePoolError,
@@ -559,11 +577,11 @@ import {
559
577
  unlinkIdentity,
560
578
  updateRuntimeController,
561
579
  updateRuntimePool
562
- } from "./cli-3nxdmjrc.js";
563
- import"./cli-cd0hv9nh.js";
580
+ } from "./cli-eejsgvm4.js";
581
+ import"./cli-ra0xzggj.js";
564
582
  import {
565
583
  bedrockProviderModule
566
- } from "./cli-h7k0xtry.js";
584
+ } from "./cli-hvqbtna4.js";
567
585
  import"./cli-phre6gz0.js";
568
586
  import"./cli-eh1ytktb.js";
569
587
  import"./cli-txgcknmy.js";
@@ -578,7 +596,7 @@ import"./cli-1m2e086m.js";
578
596
  import"./cli-btbzvq95.js";
579
597
  import"./cli-p7z6q2m6.js";
580
598
  import"./cli-wnb9b2g3.js";
581
- import"./cli-bd957dgb.js";
599
+ import"./cli-f527ce74.js";
582
600
  import {
583
601
  import_websocket,
584
602
  import_websocket_server
@@ -587,7 +605,7 @@ import"./cli-pzxba7gw.js";
587
605
  import {
588
606
  getUserGrant,
589
607
  init_rbac_roles
590
- } from "./cli-anzdk0z4.js";
608
+ } from "./cli-74ahz61x.js";
591
609
  import {
592
610
  LEGACY_RULES,
593
611
  can,
@@ -596,10 +614,12 @@ import {
596
614
  init_rbac,
597
615
  isRbacEnabled,
598
616
  setAuditSink
599
- } from "./cli-7pz3b7x5.js";
617
+ } from "./cli-przpmdgr.js";
600
618
  import {
601
619
  API_DRAINING_HEADER,
602
620
  CANDIDATE_SET_MULTIPLIER,
621
+ CHAT_SDK_ADAPTER_NAMES,
622
+ CHAT_TASK_ONLY_TOOLS,
603
623
  CODEX_AUTH_WATCH_NAMESPACE,
604
624
  CredentialBindingSchema,
605
625
  DB_RETENTION_TUNING_BOUNDS,
@@ -626,6 +646,7 @@ import {
626
646
  cancelTask,
627
647
  catalog_default,
628
648
  channelTopic,
649
+ chatThreadOfContextKey,
629
650
  checkoutPromptTemplate,
630
651
  claimKv,
631
652
  claimMentions,
@@ -715,7 +736,6 @@ import {
715
736
  getAllChannelActivityCursors,
716
737
  getAllLogs,
717
738
  getAllPricingRows,
718
- getAllServices,
719
739
  getAllSessionCosts,
720
740
  getAllTasks,
721
741
  getAllUsers,
@@ -787,7 +807,6 @@ import {
787
807
  getScriptRunByIdempotencyKey,
788
808
  getScriptRunExecutionArgs,
789
809
  getScriptRunJournalStep,
790
- getServicesByAgentId,
791
810
  getSessionCostSummary,
792
811
  getSessionCostsByAgentId,
793
812
  getSessionCostsByTaskId,
@@ -850,6 +869,7 @@ import {
850
869
  init_reranker,
851
870
  init_runtime,
852
871
  init_runtime_pools_flag,
872
+ init_schema,
853
873
  init_secret_registry,
854
874
  init_steering,
855
875
  init_swarm_config_guard,
@@ -866,6 +886,9 @@ import {
866
886
  installMcpServer,
867
887
  installSkill,
868
888
  internalConfigKeyError,
889
+ isAdapterEntryEnabled,
890
+ isApiOnlyConfigKey,
891
+ isChatSdkTask,
869
892
  isExtensionAgent,
870
893
  isFilledOrgLogoUrl,
871
894
  isInternalConfigKey,
@@ -998,9 +1021,10 @@ import {
998
1021
  upsertSkillFiles,
999
1022
  upsertSwarmConfig,
1000
1023
  validateConfigValue,
1024
+ validateExportToEnv,
1001
1025
  withFavoriteFlags
1002
- } from "./cli-fmhj1ehj.js";
1003
- import"./cli-ywm1azg9.js";
1026
+ } from "./cli-ef1hg1wv.js";
1027
+ import"./cli-hnmhtzvh.js";
1004
1028
  import {
1005
1029
  ActiveSessionSchema,
1006
1030
  AgentAcpStatusSchema,
@@ -1096,7 +1120,6 @@ import {
1096
1120
  ScriptRunStatusSchema,
1097
1121
  ScriptScopeSchema,
1098
1122
  ScriptVersionRecordSchema,
1099
- ServiceSchema,
1100
1123
  SessionCostModelBreakdownSchema,
1101
1124
  SessionCostSchema,
1102
1125
  SessionLogSchema,
@@ -1136,22 +1159,22 @@ import {
1136
1159
  isSafeBundlePath,
1137
1160
  isTerminalTaskStatus,
1138
1161
  splitLegacyModelAlias
1139
- } from "./cli-hsem16hb.js";
1162
+ } from "./cli-cgtksawx.js";
1140
1163
  import {
1141
1164
  IDENTITY_FIELD_BUDGETS,
1142
1165
  IdentityFieldBudgetError,
1143
1166
  init_identity_field_budget
1144
- } from "./cli-r4fqfpwf.js";
1145
- import {
1146
- init_steering_enabled,
1147
- isSteeringEnabled
1148
- } from "./cli-7mm2r1kp.js";
1167
+ } from "./cli-s2sp957d.js";
1149
1168
  import {
1150
1169
  getSlackConfiguration,
1151
1170
  init_config
1152
1171
  } from "./cli-dmtrxqhg.js";
1172
+ import {
1173
+ init_steering_enabled,
1174
+ isSteeringEnabled
1175
+ } from "./cli-7mm2r1kp.js";
1176
+ import"./cli-5hkm7whv.js";
1153
1177
  import"./cli-mvzyxwg3.js";
1154
- import"./cli-tadfgd0t.js";
1155
1178
  import {
1156
1179
  getAllTemplateDefinitions,
1157
1180
  getTemplateDefinition,
@@ -1178,10 +1201,7 @@ import {
1178
1201
  getOpenRouterAttributionHeaders,
1179
1202
  init_openrouter_base_url
1180
1203
  } from "./cli-a35hzdve.js";
1181
- import {
1182
- init_src,
1183
- isAlias
1184
- } from "./cli-014vns2y.js";
1204
+ import"./cli-stfs0k5s.js";
1185
1205
  import {
1186
1206
  exports_zod,
1187
1207
  init_zod
@@ -1202,17 +1222,17 @@ import {
1202
1222
  import {
1203
1223
  init_package,
1204
1224
  package_default
1205
- } from "./cli-5er5gjbm.js";
1225
+ } from "./cli-k382tshb.js";
1206
1226
  import {
1207
1227
  init_event_bus,
1208
1228
  workflowEventBus
1209
- } from "./cli-81r1wjyv.js";
1229
+ } from "./cli-9nfx44eh.js";
1210
1230
  import {
1211
1231
  init_bus,
1212
1232
  realtimeBus
1213
1233
  } from "./cli-zf8jjwex.js";
1214
1234
  import"./cli-h8w3fg83.js";
1215
- import"./cli-db3m6zdt.js";
1235
+ import"./cli-d2qr7aj4.js";
1216
1236
  import {
1217
1237
  MAX_PROFILE_FILE_LENGTH,
1218
1238
  agentFsFileRoute,
@@ -1228,7 +1248,7 @@ import {
1228
1248
  parseEnvFlag
1229
1249
  } from "./cli-ej6gbxfb.js";
1230
1250
  import"./cli-1srmzpr3.js";
1231
- import"./cli-0p3enk35.js";
1251
+ import"./cli-tqaazemc.js";
1232
1252
  import {
1233
1253
  getApiKey,
1234
1254
  init_api_key
@@ -1239,7 +1259,11 @@ import {
1239
1259
  registerVolatileSecret,
1240
1260
  scrubObject,
1241
1261
  scrubSecrets
1242
- } from "./cli-d161g69q.js";
1262
+ } from "./cli-p1x85d2t.js";
1263
+ import {
1264
+ init_src,
1265
+ isAlias
1266
+ } from "./cli-e3g5mbkz.js";
1243
1267
  import {
1244
1268
  __require,
1245
1269
  __toESM
@@ -7522,9 +7546,8 @@ init_request_auth_context();
7522
7546
  init_secret_scrubber();
7523
7547
  var MAX_ENV_PRESENCE_KEYS = 200;
7524
7548
  var SECRETS_FORCE_MASK_NOTE = " (secret values masked: this token cannot read secrets in this scope)";
7525
- var API_ONLY_CONFIG_KEYS = new Set(["API_AGENT_FS_API_KEY", "SLACK_SIGNING_SECRET"]);
7526
7549
  function stripApiOnlyKeys(configs) {
7527
- return configs.filter((config) => !API_ONLY_CONFIG_KEYS.has(config.key) && !isInternalConfigKey(config.key));
7550
+ return configs.filter((config) => !isApiOnlyConfigKey(config.key) && !isInternalConfigKey(config.key));
7528
7551
  }
7529
7552
  function singleHeader(req, name) {
7530
7553
  const raw = req.headers[name];
@@ -7566,6 +7589,9 @@ async function resolveSecretsRead(req, includeSecrets, resolvedScope) {
7566
7589
  };
7567
7590
  }
7568
7591
  async function ensureConfigAdmin(req, res, verb) {
7592
+ return ensureHttpPermission(req, res, verb, verb === "config.write.any" ? "Writing swarm config requires the lead agent" : "Deleting swarm config requires the lead agent");
7593
+ }
7594
+ async function ensureHttpPermission(req, res, verb, forbiddenMessage) {
7569
7595
  const auth = getRequestAuth(req);
7570
7596
  if (auth?.kind === "operator" || auth?.kind === "user")
7571
7597
  return true;
@@ -7582,7 +7608,7 @@ async function ensureConfigAdmin(req, res, verb) {
7582
7608
  source: "http"
7583
7609
  });
7584
7610
  if (!decision.allow) {
7585
- jsonError(res, verb === "config.write.any" ? "Writing swarm config requires the lead agent" : "Deleting swarm config requires the lead agent", 403);
7611
+ jsonError(res, forbiddenMessage, 403);
7586
7612
  return false;
7587
7613
  }
7588
7614
  return true;
@@ -7700,7 +7726,8 @@ var upsertConfig = route({
7700
7726
  value: exports_external.unknown(),
7701
7727
  isSecret: exports_external.boolean().optional(),
7702
7728
  envPath: exports_external.string().nullish(),
7703
- description: exports_external.string().nullish()
7729
+ description: exports_external.string().nullish(),
7730
+ exportToEnv: exports_external.boolean().optional().describe("Export this row into agent process env (default true on create, false for a few server-side secrets; omitted on update keeps the stored flag). Rejected as true for keys only the API server reads.")
7704
7731
  }),
7705
7732
  responses: {
7706
7733
  200: { description: "Config entry upserted", schema: SwarmConfigSchema },
@@ -7839,7 +7866,7 @@ async function handleConfig(req, res, pathSegments, queryParams) {
7839
7866
  return true;
7840
7867
  if (!await ensureConfigAdmin(req, res, "config.write.any"))
7841
7868
  return true;
7842
- const { scope, scopeId, key, value, isSecret, envPath, description } = parsed.body;
7869
+ const { scope, scopeId, key, value, isSecret, envPath, description, exportToEnv } = parsed.body;
7843
7870
  if (scope === "global" && scopeId) {
7844
7871
  jsonError(res, "Global scope must not have scopeId", 400);
7845
7872
  return true;
@@ -7856,7 +7883,7 @@ async function handleConfig(req, res, pathSegments, queryParams) {
7856
7883
  jsonError(res, internalConfigKeyError(key).message, 400);
7857
7884
  return true;
7858
7885
  }
7859
- const validationError = validateConfigValue(key, value);
7886
+ const validationError = validateConfigValue(key, value) ?? validateExportToEnv(key, exportToEnv);
7860
7887
  if (validationError) {
7861
7888
  jsonError(res, validationError, 400);
7862
7889
  return true;
@@ -7870,7 +7897,8 @@ async function handleConfig(req, res, pathSegments, queryParams) {
7870
7897
  value: String(value),
7871
7898
  isSecret: isSecret || false,
7872
7899
  envPath: envPath || null,
7873
- description: description || null
7900
+ description: description || null,
7901
+ exportToEnv
7874
7902
  });
7875
7903
  if (scope === "global" && key === "SWARM_ORG_WEBSITE") {
7876
7904
  await fillOrgLogoFromWebsite(String(value));
@@ -8428,7 +8456,7 @@ async function sendReviewBatch(input, deps = {}) {
8428
8456
  const target = targets[index];
8429
8457
  const isRepair = index >= wonIds.length;
8430
8458
  if (reply.status === "rejected") {
8431
- console.warn(scrubSecrets(`[comb] sent reply failed comment=${target.id} task=${target.taskId}: ${errorMessage(reply.reason)}`));
8459
+ console.warn(scrubSecrets(`[comb] sent reply failed comment=${target.id} task=${target.taskId}: ${errorMessage2(reply.reason)}`));
8432
8460
  if (isRepair)
8433
8461
  skipped.push(alreadySent(target.id, target.taskId));
8434
8462
  } else if (isRepair) {
@@ -8459,7 +8487,7 @@ async function readComment(agentFs, drive, versionOf, id) {
8459
8487
  } catch (error) {
8460
8488
  if (error instanceof FilesError && error.code === "NotFound")
8461
8489
  return { id, thread: null };
8462
- throw new ReviewBatchError(502, scrubSecrets(`agent-fs could not read comment ${id}: ${errorMessage(error)}`));
8490
+ throw new ReviewBatchError(502, scrubSecrets(`agent-fs could not read comment ${id}: ${errorMessage2(error)}`));
8463
8491
  }
8464
8492
  const { comment } = thread;
8465
8493
  const version = comment.fileVersion ?? (comment.parentId ? undefined : await versionOf(comment));
@@ -8519,7 +8547,7 @@ async function settleClaims(ids, claim, next) {
8519
8547
  settled.forEach((result, index) => {
8520
8548
  if (result.status === "fulfilled" && result.value)
8521
8549
  return;
8522
- const why = result.status === "rejected" ? errorMessage(result.reason) : "another send holds the claim";
8550
+ const why = result.status === "rejected" ? errorMessage2(result.reason) : "another send holds the claim";
8523
8551
  console.warn(scrubSecrets(`[comb] could not ${next ? "record" : "release"} the claim on comment=${ids[index]}: ${why}`));
8524
8552
  });
8525
8553
  }
@@ -8621,7 +8649,7 @@ async function requesterLabel(userId) {
8621
8649
  return "an operator (swarm API key)";
8622
8650
  return user.email ? `${user.name} <${user.email}>` : user.name;
8623
8651
  }
8624
- function errorMessage(error) {
8652
+ function errorMessage2(error) {
8625
8653
  return error instanceof Error ? error.message : String(error);
8626
8654
  }
8627
8655
 
@@ -8828,64 +8856,6 @@ async function handleContext(req, res, pathSegments, queryParams, myAgentId) {
8828
8856
  return false;
8829
8857
  }
8830
8858
 
8831
- // src/http/ecosystem.ts
8832
- init_zod();
8833
- init_db3();
8834
- var EcosystemAppSchema = exports_external.object({
8835
- name: exports_external.string(),
8836
- script: exports_external.string(),
8837
- cwd: exports_external.string().optional(),
8838
- interpreter: exports_external.string().optional(),
8839
- args: exports_external.array(exports_external.string()).optional(),
8840
- env: exports_external.record(exports_external.string(), exports_external.string()).optional()
8841
- });
8842
- var getEcosystem = route({
8843
- method: "get",
8844
- path: "/ecosystem",
8845
- pattern: ["ecosystem"],
8846
- summary: "Get PM2 ecosystem config for agent services",
8847
- tags: ["Ecosystem"],
8848
- auth: { apiKey: true, agentId: true },
8849
- responses: {
8850
- 200: {
8851
- description: "PM2 ecosystem config",
8852
- schema: exports_external.object({ apps: exports_external.array(EcosystemAppSchema) })
8853
- },
8854
- 400: { description: "Missing X-Agent-ID" }
8855
- }
8856
- });
8857
- async function handleEcosystem(req, res, pathSegments, myAgentId) {
8858
- if (getEcosystem.match(req.method, pathSegments)) {
8859
- if (!myAgentId) {
8860
- jsonError(res, "Missing X-Agent-ID header", 400);
8861
- return true;
8862
- }
8863
- const services = await getServicesByAgentId(myAgentId);
8864
- const ecosystem = {
8865
- apps: services.filter((s) => s.script).map((s) => {
8866
- const app = {
8867
- name: s.name,
8868
- script: s.script
8869
- };
8870
- if (s.cwd)
8871
- app.cwd = s.cwd;
8872
- if (s.interpreter)
8873
- app.interpreter = s.interpreter;
8874
- if (s.args && s.args.length > 0)
8875
- app.args = s.args;
8876
- if (s.env && Object.keys(s.env).length > 0)
8877
- app.env = s.env;
8878
- if (s.port)
8879
- app.env = { ...app.env || {}, PORT: String(s.port) };
8880
- return app;
8881
- })
8882
- };
8883
- getEcosystem.respond(res, 200, ecosystem);
8884
- return true;
8885
- }
8886
- return false;
8887
- }
8888
-
8889
8859
  // src/http/events.ts
8890
8860
  init_zod();
8891
8861
  init_types();
@@ -9107,6 +9077,7 @@ declare module "swarm-extension" {
9107
9077
  | "linear"
9108
9078
  | "jira"
9109
9079
  | "comb"
9080
+ | "chat"
9110
9081
  | undefined;
9111
9082
  routingReason?:
9112
9083
  | "skill"
@@ -9220,7 +9191,8 @@ declare module "swarm-extension" {
9220
9191
  | "system"
9221
9192
  | "linear"
9222
9193
  | "jira"
9223
- | "comb";
9194
+ | "comb"
9195
+ | "chat";
9224
9196
  tags: string[];
9225
9197
  priority: number;
9226
9198
  dependsOn: string[];
@@ -9279,6 +9251,7 @@ declare module "swarm-extension" {
9279
9251
  resolvedModel?: string | undefined;
9280
9252
  modelSource?: string | undefined;
9281
9253
  modelAlias?: string | undefined;
9254
+ resolvedEffort?: "off" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
9282
9255
  scheduleId?: string | undefined;
9283
9256
  workflowRunId?: string | null | undefined;
9284
9257
  workflowRunStepId?: string | null | undefined;
@@ -9555,6 +9528,43 @@ declare module "swarm-extension" {
9555
9528
  kind: "broadcast";
9556
9529
  };
9557
9530
  }
9531
+ /** A Chat SDK message after its thread buffer flushed, before routing. */
9532
+ export interface ChatRouteEvent {
9533
+ /** Adapter name, such as \`telegram\` or \`slack\`. */
9534
+ adapter: string;
9535
+ channelId: string;
9536
+ /** The Chat SDK thread id, prefixed with the adapter name. */
9537
+ threadId: string;
9538
+ /** The first buffered sender. */
9539
+ userId: string;
9540
+ userName?: string;
9541
+ /** The buffered messages, joined. */
9542
+ text: string;
9543
+ botMentioned: boolean;
9544
+ isDirectMessage: boolean;
9545
+ /** Set when earlier swarm tasks exist in this thread. */
9546
+ threadContext?: {
9547
+ adapter: string;
9548
+ threadId: string;
9549
+ };
9550
+ }
9551
+ export interface ChatRouteModify {
9552
+ target:
9553
+ | {
9554
+ kind: "agent";
9555
+ agentId: string;
9556
+ }
9557
+ | {
9558
+ kind: "lead";
9559
+ }
9560
+ | {
9561
+ kind: "broadcast";
9562
+ }
9563
+ | {
9564
+ kind: "workflow";
9565
+ workflowId: string;
9566
+ };
9567
+ }
9558
9568
  export type HeartbeatClassification = "no-session" | "stale-session" | "fresh-stalled";
9559
9569
  export type HeartbeatAction = "supersede-resume" | "fail" | "record";
9560
9570
  export interface HeartbeatRemediateEvent {
@@ -9599,6 +9609,18 @@ declare module "swarm-extension" {
9599
9609
  threadTs?: string;
9600
9610
  taskId?: string;
9601
9611
  }
9612
+ /** A Chat SDK message the swarm received or sent. */
9613
+ export interface ChatMessageEvent {
9614
+ adapter: string;
9615
+ channelId: string;
9616
+ threadId: string;
9617
+ /** The sender, for an inbound message. */
9618
+ userId?: string;
9619
+ text: string;
9620
+ direction: "inbound" | "outbound";
9621
+ taskId?: string;
9622
+ messageId?: string;
9623
+ }
9602
9624
  /**
9603
9625
  * A person answered an approval request. Fires for workflow and standalone
9604
9626
  * requests. Timeouts and cancellations do not emit it today.
@@ -9707,6 +9729,11 @@ declare module "swarm-extension" {
9707
9729
  modify: SlackRouteModify;
9708
9730
  result: PreResult<SlackRouteModify>;
9709
9731
  };
9732
+ "pre.chat.route": {
9733
+ event: ChatRouteEvent;
9734
+ modify: ChatRouteModify;
9735
+ result: PreResult<ChatRouteModify>;
9736
+ };
9710
9737
  "pre.heartbeat.remediate": {
9711
9738
  event: HeartbeatRemediateEvent;
9712
9739
  modify: HeartbeatRemediateModify;
@@ -9752,6 +9779,11 @@ declare module "swarm-extension" {
9752
9779
  modify: never;
9753
9780
  result: void;
9754
9781
  };
9782
+ "post.chat.message": {
9783
+ event: ChatMessageEvent;
9784
+ modify: never;
9785
+ result: void;
9786
+ };
9755
9787
  "post.approval.resolved": {
9756
9788
  event: ApprovalResolvedEvent;
9757
9789
  modify: never;
@@ -12808,6 +12840,203 @@ async function handleInboxState(req, res, pathSegments, queryParams) {
12808
12840
 
12809
12841
  // src/http/integrations.ts
12810
12842
  init_zod();
12843
+
12844
+ // src/integrations/chat-sdk/status.ts
12845
+ init_zod();
12846
+ init_constants();
12847
+ init_env_flag();
12848
+ init_secret_scrubber();
12849
+
12850
+ // src/integrations/chat-sdk/discord-api.ts
12851
+ init_secret_scrubber();
12852
+ var DISCORD_TIMEOUT_MS = 5000;
12853
+ var GUILDS_CACHE_MS = 60000;
12854
+ var MAX_GUILD_NAMES = 10;
12855
+ var cache;
12856
+ async function fetchDiscordGuilds(token, now = Date.now()) {
12857
+ if (cache && cache.token === token && now - cache.at < GUILDS_CACHE_MS)
12858
+ return cache.guilds;
12859
+ let guilds;
12860
+ try {
12861
+ const response = await fetch(`${resolveAdapterApiUrl("discord")}/users/@me/guilds`, {
12862
+ headers: { authorization: `Bot ${token}` },
12863
+ signal: AbortSignal.timeout(DISCORD_TIMEOUT_MS)
12864
+ });
12865
+ if (!response.ok)
12866
+ throw new Error(`HTTP ${response.status}`);
12867
+ const payload = await response.json();
12868
+ if (!Array.isArray(payload))
12869
+ throw new Error("unexpected response shape");
12870
+ const names = payload.map((guild) => guild !== null && typeof guild === "object" && typeof guild.name === "string" ? guild.name : undefined).filter((name) => name !== undefined);
12871
+ guilds = { count: payload.length, names: names.slice(0, MAX_GUILD_NAMES) };
12872
+ } catch (error) {
12873
+ console.warn(scrubSecrets(`[chat-sdk] discord: could not list the bot's servers: ${errorMessage(error).replaceAll(token, "[REDACTED]")}`));
12874
+ }
12875
+ cache = { token, at: now, guilds };
12876
+ return guilds;
12877
+ }
12878
+
12879
+ // src/integrations/chat-sdk/status.ts
12880
+ init_schema();
12881
+ var ChatSdkStatusSchema = exports_external.object({
12882
+ enabled: exports_external.boolean(),
12883
+ slackClash: exports_external.boolean(),
12884
+ error: exports_external.string().optional(),
12885
+ adapters: exports_external.array(exports_external.object({
12886
+ name: exports_external.enum(CHAT_SDK_ADAPTER_NAMES),
12887
+ configured: exports_external.boolean(),
12888
+ enabled: exports_external.boolean(),
12889
+ health: exports_external.enum(["ok", "error", "disabled", "incomplete"]),
12890
+ error: exports_external.string().optional(),
12891
+ webhookUrl: exports_external.string(),
12892
+ mode: exports_external.string().optional(),
12893
+ gateway: exports_external.object({
12894
+ state: exports_external.enum(["running", "backoff", "stopped"]),
12895
+ since: exports_external.string(),
12896
+ restarts: exports_external.number()
12897
+ }).optional(),
12898
+ guilds: exports_external.object({ count: exports_external.number(), names: exports_external.array(exports_external.string()) }).optional()
12899
+ }))
12900
+ });
12901
+ var DEFAULT_MODES = {
12902
+ telegram: "webhook",
12903
+ slack: "webhook"
12904
+ };
12905
+ var NOT_RUNNING = "The adapter is starting, or the last configuration save is still applying. Refresh in a few seconds.";
12906
+ var SLACK_CLASH_CAUSE = "the Slack adapter conflicts with the built-in Slack integration (set SLACK_DISABLE=true)";
12907
+ var MAX_STATUS_ERROR_CHARS = 300;
12908
+ function statusError(message) {
12909
+ return scrubSecrets(message).slice(0, MAX_STATUS_ERROR_CHARS);
12910
+ }
12911
+ function readRawAdapters() {
12912
+ const raw = process.env.CHAT_SDK_ADAPTERS?.trim();
12913
+ if (!raw)
12914
+ return {};
12915
+ try {
12916
+ const parsed = JSON.parse(raw);
12917
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
12918
+ return {};
12919
+ const out = {};
12920
+ for (const name of CHAT_SDK_ADAPTER_NAMES) {
12921
+ const value = parsed[name];
12922
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
12923
+ out[name] = value;
12924
+ }
12925
+ }
12926
+ return out;
12927
+ } catch {
12928
+ return {};
12929
+ }
12930
+ }
12931
+ function chatSdkWebhookUrl(name) {
12932
+ return `${getPublicMcpBaseUrl()}/api/integrations/chat/${name}/webhook`;
12933
+ }
12934
+ async function discordGuildsFor(config, health) {
12935
+ if (health?.status !== "ok" || health.gateway?.state !== "running")
12936
+ return;
12937
+ const raw = config.adapters.discord?.botToken;
12938
+ const token = typeof raw === "function" ? await raw() : raw;
12939
+ if (typeof token !== "string" || token.length === 0)
12940
+ return;
12941
+ return fetchDiscordGuilds(token);
12942
+ }
12943
+ async function getChatSdkStatus() {
12944
+ const config = await getChatSdkConfig();
12945
+ const raw = readRawAdapters();
12946
+ const runtimeHealth = getChatSdkHealth();
12947
+ const slackClash = raw.slack !== undefined && !isEnvFlagEnabled("SLACK_DISABLE", false);
12948
+ const blockedCause = config.error ?? (config.enabled && slackClash ? SLACK_CLASH_CAUSE : undefined);
12949
+ const discordGuilds = await discordGuildsFor(config, runtimeHealth.discord);
12950
+ const adapters = CHAT_SDK_ADAPTER_NAMES.map((name) => {
12951
+ const configured = raw[name] !== undefined;
12952
+ const enabled = isAdapterEntryEnabled(raw[name]);
12953
+ const current = runtimeHealth[name];
12954
+ const incomplete = config.incomplete?.[name];
12955
+ const rawMode = raw[name]?.mode;
12956
+ const mode = typeof rawMode === "string" ? rawMode : configured ? DEFAULT_MODES[name] : undefined;
12957
+ let health = "disabled";
12958
+ let error;
12959
+ if (current) {
12960
+ health = current.status;
12961
+ const showWarning = current.status === "error" || current.gateway?.state === "backoff";
12962
+ error = current.error ?? (showWarning ? current.lastWarning : undefined);
12963
+ } else if (incomplete) {
12964
+ health = "incomplete";
12965
+ error = incomplete;
12966
+ } else if (configured && !enabled) {
12967
+ error = "Turned off on the card. The configuration is kept.";
12968
+ } else if (config.enabled && configured) {
12969
+ error = blockedCause ? `Not started: ${blockedCause}` : NOT_RUNNING;
12970
+ }
12971
+ return {
12972
+ name,
12973
+ configured,
12974
+ enabled,
12975
+ health,
12976
+ ...error ? { error: statusError(error) } : {},
12977
+ webhookUrl: chatSdkWebhookUrl(name),
12978
+ ...mode ? { mode } : {},
12979
+ ...current?.gateway ? { gateway: current.gateway } : {},
12980
+ ...name === "discord" && discordGuilds ? { guilds: discordGuilds } : {}
12981
+ };
12982
+ });
12983
+ return {
12984
+ enabled: config.enabled,
12985
+ slackClash,
12986
+ ...config.error ? { error: statusError(config.error) } : {},
12987
+ adapters
12988
+ };
12989
+ }
12990
+
12991
+ class ChatSdkActionError extends Error {
12992
+ status;
12993
+ constructor(message, status) {
12994
+ super(message);
12995
+ this.status = status;
12996
+ this.name = "ChatSdkActionError";
12997
+ }
12998
+ }
12999
+ async function callBotApi(baseUrl, token, method, body) {
13000
+ try {
13001
+ return await callTelegramBotApi(baseUrl, token, method, body);
13002
+ } catch (error) {
13003
+ if (error instanceof TelegramBotApiError)
13004
+ throw new ChatSdkActionError(error.message, 502);
13005
+ throw error;
13006
+ }
13007
+ }
13008
+ async function registerTelegramWebhook() {
13009
+ const config = await getChatSdkConfig();
13010
+ if (!config.enabled) {
13011
+ throw new ChatSdkActionError("The Chat SDK channel is disabled (CHAT_SDK_ENABLED is not true). Enable it and restart the API first", 400);
13012
+ }
13013
+ if (config.error)
13014
+ throw new ChatSdkActionError(statusError(config.error), 400);
13015
+ const telegram = config.adapters.telegram;
13016
+ if (!telegram) {
13017
+ throw new ChatSdkActionError("Telegram is not configured in CHAT_SDK_ADAPTERS", 400);
13018
+ }
13019
+ if (telegram.mode !== "webhook") {
13020
+ throw new ChatSdkActionError("Telegram runs in polling mode; a registered webhook would stop polling", 400);
13021
+ }
13022
+ const secretToken = telegram.secretToken;
13023
+ if (typeof secretToken !== "string" || secretToken.length === 0) {
13024
+ throw new ChatSdkActionError("Telegram webhook mode needs a secretToken", 400);
13025
+ }
13026
+ const rawToken = telegram.botToken;
13027
+ const token = typeof rawToken === "function" ? await rawToken() : rawToken;
13028
+ if (typeof token !== "string" || token.length === 0) {
13029
+ throw new ChatSdkActionError("Telegram botToken is empty", 400);
13030
+ }
13031
+ const baseUrl = resolveAdapterApiUrl("telegram");
13032
+ const webhookUrl = chatSdkWebhookUrl("telegram");
13033
+ await callBotApi(baseUrl, token, "setWebhook", { url: webhookUrl, secret_token: secretToken });
13034
+ const info = await callBotApi(baseUrl, token, "getWebhookInfo", {});
13035
+ if (info === null || typeof info !== "object" || typeof info.url !== "string") {
13036
+ throw new ChatSdkActionError("Telegram getWebhookInfo returned an unexpected result", 502);
13037
+ }
13038
+ return { webhookUrl, webhookInfo: info };
13039
+ }
12811
13040
  // slack-manifest.json
12812
13041
  var slack_manifest_default = {
12813
13042
  display_information: {
@@ -12983,6 +13212,19 @@ var McpUserConfigSchema = exports_external.object({
12983
13212
  mcpUserUrl: exports_external.string()
12984
13213
  });
12985
13214
  var SlackManifestSchema = exports_external.record(exports_external.string(), exports_external.unknown());
13215
+ var TelegramRegisterWebhookSchema = exports_external.object({
13216
+ webhookUrl: exports_external.string(),
13217
+ webhookInfo: exports_external.looseObject({
13218
+ url: exports_external.string(),
13219
+ has_custom_certificate: exports_external.boolean().optional(),
13220
+ pending_update_count: exports_external.number().optional(),
13221
+ last_error_date: exports_external.number().optional(),
13222
+ last_error_message: exports_external.string().optional(),
13223
+ max_connections: exports_external.number().optional(),
13224
+ ip_address: exports_external.string().optional(),
13225
+ allowed_updates: exports_external.array(exports_external.string()).optional()
13226
+ })
13227
+ });
12986
13228
  var claudeManagedTestRoute = route({
12987
13229
  method: "post",
12988
13230
  path: "/api/integrations/claude-managed/test",
@@ -13021,6 +13263,34 @@ var slackManifestRoute = route({
13021
13263
  200: { description: "Slack app manifest", schema: SlackManifestSchema }
13022
13264
  }
13023
13265
  });
13266
+ var chatSdkStatusRoute = route({
13267
+ method: "get",
13268
+ path: "/api/integrations/chat/status",
13269
+ pattern: ["api", "integrations", "chat", "status"],
13270
+ summary: "Chat SDK channel status: enabled flag, Slack clash, per-adapter health and webhook URL.",
13271
+ tags: ["Integrations"],
13272
+ responses: {
13273
+ 200: {
13274
+ description: "Per-adapter status. `health` is `disabled` for an adapter that is not running. Never contains secret values.",
13275
+ schema: ChatSdkStatusSchema
13276
+ }
13277
+ }
13278
+ });
13279
+ var chatSdkTelegramRegisterWebhookRoute = route({
13280
+ method: "post",
13281
+ path: "/api/integrations/chat/telegram/register-webhook",
13282
+ pattern: ["api", "integrations", "chat", "telegram", "register-webhook"],
13283
+ summary: "Register this swarm's public Telegram webhook URL and secret token with the Bot API (setWebhook), then return getWebhookInfo.",
13284
+ tags: ["Integrations"],
13285
+ body: exports_external.object({}).optional(),
13286
+ responses: {
13287
+ 200: { description: "Webhook registered", schema: TelegramRegisterWebhookSchema },
13288
+ 400: { description: "Telegram is not configured for webhook mode" },
13289
+ 403: { description: "Only the lead agent or a dashboard user can register the webhook" },
13290
+ 502: { description: "The Telegram Bot API rejected the call" }
13291
+ },
13292
+ rbac: { permission: "integration.chat.manage" }
13293
+ });
13024
13294
  function createIntegrationsHandler(deps = {}) {
13025
13295
  const buildClient = deps.buildClient ?? ((apiKey) => new Anthropic({ apiKey }));
13026
13296
  return async function handleIntegrations(req, res, pathSegments, queryParams = new URLSearchParams) {
@@ -13031,6 +13301,26 @@ function createIntegrationsHandler(deps = {}) {
13031
13301
  slackManifestRoute.respond(res, 200, buildSlackManifest(parsed.query.name));
13032
13302
  return true;
13033
13303
  }
13304
+ if (chatSdkStatusRoute.match(req.method, pathSegments)) {
13305
+ chatSdkStatusRoute.respond(res, 200, await getChatSdkStatus());
13306
+ return true;
13307
+ }
13308
+ if (chatSdkTelegramRegisterWebhookRoute.match(req.method, pathSegments)) {
13309
+ const parsed = await chatSdkTelegramRegisterWebhookRoute.parse(req, res, pathSegments, queryParams);
13310
+ if (!parsed)
13311
+ return true;
13312
+ if (!await ensureHttpPermission(req, res, "integration.chat.manage", "Registering the Telegram webhook requires the lead agent")) {
13313
+ return true;
13314
+ }
13315
+ try {
13316
+ chatSdkTelegramRegisterWebhookRoute.respond(res, 200, await registerTelegramWebhook());
13317
+ } catch (error) {
13318
+ if (!(error instanceof ChatSdkActionError))
13319
+ throw error;
13320
+ jsonError(res, error.message, error.status);
13321
+ }
13322
+ return true;
13323
+ }
13034
13324
  if (mcpUserConfigRoute.match(req.method, pathSegments)) {
13035
13325
  const mcpBaseUrl = await resolveMcpBaseUrl();
13036
13326
  mcpUserConfigRoute.respond(res, 200, { mcpBaseUrl, mcpUserUrl: `${mcpBaseUrl}/mcp-user` });
@@ -13662,7 +13952,7 @@ var toRequestError = (e) => {
13662
13952
  return new RequestError(e.message, { cause: e });
13663
13953
  };
13664
13954
  var GlobalRequest = global.Request;
13665
- var Request = class extends GlobalRequest {
13955
+ var Request2 = class extends GlobalRequest {
13666
13956
  constructor(input, options) {
13667
13957
  if (typeof input === "object" && getRequestCache in input) {
13668
13958
  input = input[getRequestCache]();
@@ -13693,7 +13983,7 @@ var newRequestFromIncoming = (method, url, headers2, incoming, abortController)
13693
13983
  };
13694
13984
  if (method === "TRACE") {
13695
13985
  init.method = "GET";
13696
- const req = new Request(url, init);
13986
+ const req = new Request2(url, init);
13697
13987
  Object.defineProperty(req, "method", {
13698
13988
  get() {
13699
13989
  return "TRACE";
@@ -13730,7 +14020,7 @@ var newRequestFromIncoming = (method, url, headers2, incoming, abortController)
13730
14020
  init.body = Readable.toWeb(incoming);
13731
14021
  }
13732
14022
  }
13733
- return new Request(url, init);
14023
+ return new Request2(url, init);
13734
14024
  };
13735
14025
  var getRequestCache = Symbol("getRequestCache");
13736
14026
  var requestCache = Symbol("requestCache");
@@ -13796,7 +14086,7 @@ Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom")
13796
14086
  return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
13797
14087
  }
13798
14088
  });
13799
- Object.setPrototypeOf(requestPrototype, Request.prototype);
14089
+ Object.setPrototypeOf(requestPrototype, Request2.prototype);
13800
14090
  var newRequest = (incoming, defaultHostname) => {
13801
14091
  const req = Object.create(requestPrototype);
13802
14092
  req[incomingKey] = incoming;
@@ -13865,12 +14155,12 @@ var Response2 = class _Response {
13865
14155
  }
13866
14156
  }
13867
14157
  get headers() {
13868
- const cache = this[cacheKey];
13869
- if (cache) {
13870
- if (!(cache[2] instanceof Headers)) {
13871
- cache[2] = new Headers(cache[2] || { "content-type": "text/plain; charset=UTF-8" });
14158
+ const cache2 = this[cacheKey];
14159
+ if (cache2) {
14160
+ if (!(cache2[2] instanceof Headers)) {
14161
+ cache2[2] = new Headers(cache2[2] || { "content-type": "text/plain; charset=UTF-8" });
13872
14162
  }
13873
- return cache[2];
14163
+ return cache2[2];
13874
14164
  }
13875
14165
  return this[getResponseCache]().headers;
13876
14166
  }
@@ -14158,9 +14448,9 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
14158
14448
  };
14159
14449
  var getRequestListener = (fetchCallback, options = {}) => {
14160
14450
  const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
14161
- if (options.overrideGlobalObjects !== false && global.Request !== Request) {
14451
+ if (options.overrideGlobalObjects !== false && global.Request !== Request2) {
14162
14452
  Object.defineProperty(global, "Request", {
14163
- value: Request
14453
+ value: Request2
14164
14454
  });
14165
14455
  Object.defineProperty(global, "Response", {
14166
14456
  value: Response2
@@ -15200,13 +15490,14 @@ async function handleMcp(req, res, transports, sessionActivity = {}, sessionAgen
15200
15490
  const configValue = configs.find((config) => config.key === "SCRIPTS_ONLY_MCP")?.value;
15201
15491
  const preloadEnabled = parseEnvFlag(configs.find((config) => config.key === "TASK_TOOL_PRELOAD_ENABLED")?.value ?? process.env.TASK_TOOL_PRELOAD_ENABLED, true);
15202
15492
  let preloadedTools = [];
15493
+ const sourceTaskId = headerValue(req.headers["x-source-task-id"]);
15494
+ const sourceTask = sourceTaskId ? await getTaskById(sourceTaskId) : undefined;
15495
+ const excludedTools = sourceTask && !isChatSdkTask(sourceTask) ? [...CHAT_TASK_ONLY_TOOLS] : [];
15203
15496
  if (preloadEnabled) {
15204
- const taskId = headerValue(req.headers["x-source-task-id"]);
15205
- const task = taskId ? await getTaskById(taskId) : undefined;
15206
- if (task?.agentId === agentId) {
15497
+ if (sourceTask?.agentId === agentId) {
15207
15498
  const manifestValue = configs.find((config) => config.key === "TASK_TOOL_MANIFESTS")?.value ?? process.env.TASK_TOOL_MANIFESTS ?? "{}";
15208
15499
  try {
15209
- preloadedTools = selectTaskTools(parseTaskToolManifest(manifestValue), task);
15500
+ preloadedTools = selectTaskTools(parseTaskToolManifest(manifestValue), sourceTask);
15210
15501
  } catch {
15211
15502
  console.warn("[MCP] Invalid TASK_TOOL_MANIFESTS; using ordinary tool discovery");
15212
15503
  }
@@ -15214,6 +15505,7 @@ async function handleMcp(req, res, transports, sessionActivity = {}, sessionAgen
15214
15505
  }
15215
15506
  const server = await createServer({
15216
15507
  preloadedTools,
15508
+ excludedTools,
15217
15509
  enabledTools: configs.find((config) => config.key === "SWARM_ENABLED_TOOLS")?.value ?? process.env.SWARM_ENABLED_TOOLS,
15218
15510
  scriptsOnly: resolveScriptsOnlyMode({
15219
15511
  env: process.env.SCRIPTS_ONLY_MCP,
@@ -20504,9 +20796,47 @@ init_db3();
20504
20796
  init_steering();
20505
20797
  init_users();
20506
20798
  init_rbac();
20799
+ init_context_key();
20507
20800
  init_types();
20508
20801
  init_request_auth_context();
20509
20802
  init_secret_scrubber();
20803
+
20804
+ // src/http/requested-by.ts
20805
+ init_zod();
20806
+ init_db3();
20807
+ init_types();
20808
+ var TaskRequestedBySchema = UserSchema.pick({
20809
+ id: true,
20810
+ name: true,
20811
+ email: true,
20812
+ role: true,
20813
+ notes: true
20814
+ }).extend({
20815
+ id: exports_external.string().optional(),
20816
+ comms: UserCommsPrefsSchema.optional()
20817
+ });
20818
+ function getRequesterNotes(notes) {
20819
+ return typeof notes === "string" && notes.trim().length > 0 ? notes : undefined;
20820
+ }
20821
+ async function buildTaskRequestedBy(task) {
20822
+ const user = task.requestedByUserId ? await getUserById(task.requestedByUserId) : undefined;
20823
+ if (user) {
20824
+ return {
20825
+ id: user.id,
20826
+ name: user.name,
20827
+ email: user.email,
20828
+ role: user.role,
20829
+ notes: getRequesterNotes(user.notes),
20830
+ comms: getUserCommsPrefs(user)
20831
+ };
20832
+ }
20833
+ if (task.slackUserId) {
20834
+ return { name: renderIdentity(await resolveIdentity("slack", task.slackUserId)) };
20835
+ }
20836
+ return;
20837
+ }
20838
+
20839
+ // src/http/tasks.ts
20510
20840
  var AgentTaskSummarySchema = AgentTaskSchema.pick({
20511
20841
  id: true,
20512
20842
  key: true,
@@ -20530,6 +20860,7 @@ var AgentTaskSummarySchema = AgentTaskSchema.pick({
20530
20860
  modelSource: true,
20531
20861
  modelAlias: true,
20532
20862
  effort: true,
20863
+ resolvedEffort: true,
20533
20864
  provider: true,
20534
20865
  requestedByUserId: true,
20535
20866
  progress: true,
@@ -20673,6 +21004,9 @@ var createTask = route({
20673
21004
  400: {
20674
21005
  description: "Validation error, an unknown `model` (set `allowCustomModel` to store a custom id), or agentId/offeredTo targets an extension identity"
20675
21006
  },
21007
+ 403: {
21008
+ description: "An agent caller names a parentTaskId it neither owns nor created, or a non-lead agent binds the task to a chat thread"
21009
+ },
20676
21010
  422: {
20677
21011
  description: "Task creation blocked by an extension",
20678
21012
  schema: exports_external.object({
@@ -20719,6 +21053,7 @@ var updateSession = route({
20719
21053
  claudeSessionId: exports_external.string().min(1),
20720
21054
  provider: ProviderNameSchema.exclude(["devin"]).optional(),
20721
21055
  model: exports_external.string().optional(),
21056
+ effort: ReasoningEffortSchema.nullable().optional(),
20722
21057
  providerMeta: exports_external.object({ transport: exports_external.enum(["cli", "sdk"]).optional() }).optional(),
20723
21058
  harnessVariant: exports_external.string().optional(),
20724
21059
  harnessVariantMeta: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
@@ -20933,7 +21268,10 @@ var listPausedTasks = route({
20933
21268
  200: {
20934
21269
  description: "Paused task list",
20935
21270
  schema: exports_external.object({
20936
- tasks: exports_external.array(AgentTaskSchema.extend({ attachments: exports_external.array(TaskAttachmentSchema) }))
21271
+ tasks: exports_external.array(AgentTaskSchema.extend({
21272
+ attachments: exports_external.array(TaskAttachmentSchema),
21273
+ requestedBy: TaskRequestedBySchema.optional()
21274
+ }))
20937
21275
  })
20938
21276
  }
20939
21277
  }
@@ -21193,6 +21531,26 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
21193
21531
  return true;
21194
21532
  }
21195
21533
  const parentTask = parsed.body.parentTaskId ? await getTaskById(parsed.body.parentTaskId) : null;
21534
+ const principal = await resolveTaskWritePrincipal(req, myAgentId);
21535
+ if (parentTask && !can({
21536
+ principal,
21537
+ verb: "task.parent.attach",
21538
+ resource: {
21539
+ kind: "task",
21540
+ taskId: parentTask.id,
21541
+ requestedByUserId: parentTask.requestedByUserId,
21542
+ creatorAgentId: parentTask.creatorAgentId,
21543
+ agentId: parentTask.agentId
21544
+ },
21545
+ source: "http"
21546
+ }).allow) {
21547
+ jsonError(res, `You don't have context for parent task ${parentTask.id}.`, 403);
21548
+ return true;
21549
+ }
21550
+ if (principal.kind === "agent" && parsed.body.contextKey && parsed.body.contextKey !== parentTask?.contextKey && chatThreadOfContextKey(parsed.body.contextKey) && !can({ principal, verb: "integration.chat.post", resource: { kind: "none" }, source: "http" }).allow) {
21551
+ jsonError(res, "Permission denied: only a lead can bind a task to a chat thread.", 403);
21552
+ return true;
21553
+ }
21196
21554
  let assetKey;
21197
21555
  try {
21198
21556
  const inheritedKey = parentTask?.key;
@@ -21287,7 +21645,7 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
21287
21645
  const parsed = await updateSession.parse(req, res, pathSegments, queryParams);
21288
21646
  if (!parsed)
21289
21647
  return true;
21290
- const task = await updateTaskClaudeSessionId(parsed.params.id, parsed.body.claudeSessionId, parsed.body.provider, parsed.body.providerMeta, parsed.body.model, "harnessVariant" in parsed.body ? parsed.body.harnessVariant : undefined, "harnessVariantMeta" in parsed.body ? parsed.body.harnessVariantMeta : undefined);
21648
+ const task = await updateTaskClaudeSessionId(parsed.params.id, parsed.body.claudeSessionId, parsed.body.provider, parsed.body.providerMeta, parsed.body.model, "harnessVariant" in parsed.body ? parsed.body.harnessVariant : undefined, "harnessVariantMeta" in parsed.body ? parsed.body.harnessVariantMeta : undefined, "effort" in parsed.body ? parsed.body.effort : undefined);
21291
21649
  if (!task) {
21292
21650
  jsonError(res, "Task not found", 404);
21293
21651
  return true;
@@ -21727,10 +22085,14 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
21727
22085
  return true;
21728
22086
  }
21729
22087
  const pausedTasks = await getPausedTasksForAgent(myAgentId);
21730
- const tasks = await Promise.all(pausedTasks.map(async (task) => ({
21731
- ...task,
21732
- attachments: await getTaskAttachments(task.id)
21733
- })));
22088
+ const tasks = await Promise.all(pausedTasks.map(async (task) => {
22089
+ const requestedBy = await buildTaskRequestedBy(task);
22090
+ return {
22091
+ ...task,
22092
+ attachments: await getTaskAttachments(task.id),
22093
+ ...requestedBy && { requestedBy }
22094
+ };
22095
+ }));
21734
22096
  listPausedTasks.respond(res, 200, { tasks });
21735
22097
  return true;
21736
22098
  }
@@ -22236,10 +22598,6 @@ function withShareUrls(page) {
22236
22598
  app_url: `${getAppBaseUrl()}/pages/${page.slug}`
22237
22599
  };
22238
22600
  }
22239
- async function pageEditCounter(pageId) {
22240
- const versions = await getPageVersions(pageId);
22241
- return versions.length > 0 ? versions[0].version + 1 : 1;
22242
- }
22243
22601
  function defuseFeedbackTags(value) {
22244
22602
  return value.replace(/<(\/?page_feedback)/gi, "‹$1");
22245
22603
  }
@@ -22513,7 +22871,7 @@ async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
22513
22871
  updatePageRoute.respond(res, 200, {
22514
22872
  id: updated.id,
22515
22873
  key: updated.key,
22516
- version: await pageEditCounter(updated.id)
22874
+ version: await getPageEditCounter(updated.id)
22517
22875
  });
22518
22876
  return true;
22519
22877
  }
@@ -22635,8 +22993,819 @@ ${defuseFeedbackTags(note)}
22635
22993
 
22636
22994
  // src/http/pages-public.ts
22637
22995
  init_zod();
22996
+ init_db3();
22997
+
22998
+ // src/pages/browser-sdk.ts
22999
+ var BROWSER_SDK_JS = `
23000
+ class SwarmSDK {
23001
+ constructor() {
23002
+ let realtime;
23003
+ const loadRealtime = () => realtime || (realtime = import('/@swarm/realtime.js'));
23004
+ this.room = async (name, options) => (await loadRealtime()).room(name, options);
23005
+ this.channel = async (name) => (await loadRealtime()).channel(name);
23006
+
23007
+ const base = '/@swarm/api';
23008
+ const call = async (method, path, body) => {
23009
+ const init = { method };
23010
+ if (body !== undefined) {
23011
+ init.headers = { 'Content-Type': 'application/json' };
23012
+ init.body = JSON.stringify(body);
23013
+ }
23014
+ const res = await fetch(base + path, init);
23015
+ const text = await res.text();
23016
+ let parsed = null;
23017
+ if (text) {
23018
+ try { parsed = JSON.parse(text); } catch { parsed = text; }
23019
+ }
23020
+ if (!res.ok) {
23021
+ const err = new Error('SwarmSDK ' + method + ' ' + path + ': ' + res.status);
23022
+ err.status = res.status;
23023
+ err.response = parsed;
23024
+ throw err;
23025
+ }
23026
+ return parsed;
23027
+ };
23028
+ const qs = (obj) => {
23029
+ if (!obj) return '';
23030
+ const p = new URLSearchParams();
23031
+ for (const [k, v] of Object.entries(obj)) {
23032
+ if (v === undefined || v === null) continue;
23033
+ p.set(k, String(v));
23034
+ }
23035
+ const s = p.toString();
23036
+ return s ? '?' + s : '';
23037
+ };
23038
+ const enc = encodeURIComponent;
23039
+
23040
+ this.tasks = {
23041
+ create: (body) => call('POST', '/tasks', body),
23042
+ list: (filters) => call('GET', '/tasks' + qs(filters)),
23043
+ get: (id) => call('GET', '/tasks/' + enc(id)),
23044
+ storeProgress: (id, data) => call('POST', '/tasks/' + enc(id) + '/progress', data),
23045
+ };
23046
+
23047
+ this.agents = {
23048
+ list: () => call('GET', '/agents'),
23049
+ get: (id) => call('GET', '/agents/' + enc(id)),
23050
+ };
23051
+
23052
+ this.events = {
23053
+ create: (body) => call('POST', '/events', body),
23054
+ list: (filters) => call('GET', '/events' + qs(filters)),
23055
+ batch: (body) => call('POST', '/events/batch', body),
23056
+ counts: (filters) => call('GET', '/events/counts' + qs(filters)),
23057
+ };
22638
23058
 
22639
- // src/artifact-sdk/feedback-overlay.ts
23059
+ this.memory = {
23060
+ search: (body) => call('POST', '/memory/search', body),
23061
+ list: (filters) => call('GET', '/memory/list' + qs(filters)),
23062
+ get: (id) => call('GET', '/memory/' + enc(id)),
23063
+ rate: (body) => call('POST', '/memory/rate', body),
23064
+ };
23065
+
23066
+ this.repos = {
23067
+ list: () => call('GET', '/repos'),
23068
+ get: (id) => call('GET', '/repos/' + enc(id)),
23069
+ create: (body) => call('POST', '/repos', body),
23070
+ update: (id, body) => call('PUT', '/repos/' + enc(id), body),
23071
+ delete: (id) => call('DELETE', '/repos/' + enc(id)),
23072
+ };
23073
+
23074
+ this.schedules = {
23075
+ list: () => call('GET', '/schedules'),
23076
+ get: (id) => call('GET', '/schedules/' + enc(id)),
23077
+ create: (body) => call('POST', '/schedules', body),
23078
+ update: (id, body) => call('PUT', '/schedules/' + enc(id), body),
23079
+ delete: (id) => call('DELETE', '/schedules/' + enc(id)),
23080
+ run: (id) => call('POST', '/schedules/' + enc(id) + '/run'),
23081
+ };
23082
+
23083
+ this.approvalRequests = {
23084
+ list: (filters) => call('GET', '/approval-requests' + qs(filters)),
23085
+ get: (id) => call('GET', '/approval-requests/' + enc(id)),
23086
+ create: (body) => call('POST', '/approval-requests', body),
23087
+ respond: (id, body) => call('POST', '/approval-requests/' + enc(id) + '/respond', body),
23088
+ };
23089
+
23090
+ this.assets = {
23091
+ list: (filters) => call('GET', '/assets' + qs(filters)),
23092
+ audit: () => call('GET', '/assets/key-audit'),
23093
+ registerMapping: (body) => call('POST', '/assets/mappings', body),
23094
+ move: (entityType, id, key) => call(
23095
+ 'PATCH',
23096
+ '/assets/' + enc(entityType) + '/' + enc(id) + '/key',
23097
+ { key },
23098
+ ),
23099
+ };
23100
+
23101
+ // KV store. The namespace is FORCED by the page-proxy to \`task:page:<id>\`
23102
+ // (it injects X-Page-Id which the kv handler treats as highest priority).
23103
+ // No namespace argument is exposed — pages cannot read/write any other
23104
+ // namespace via this SDK.
23105
+ this.kv = {
23106
+ get: (key) => call('GET', '/kv/' + enc(key)),
23107
+ set: (key, value, opts) => call('PUT', '/kv/' + enc(key), {
23108
+ value,
23109
+ valueType: opts && opts.valueType,
23110
+ expiresInSec: opts && opts.expiresInSec,
23111
+ }),
23112
+ del: (key) => call('DELETE', '/kv/' + enc(key)),
23113
+ incr: (key, by) => call('POST', '/kv/' + enc(key) + '/incr', { by: by == null ? 1 : by }),
23114
+ list: (opts) => call('GET', '/kv' + qs(opts)),
23115
+ };
23116
+ }
23117
+ }
23118
+
23119
+ // Expose BOTH the class (for \`new SwarmSDK()\`) AND a ready-to-use singleton
23120
+ // on \`window.swarmSdk\` so pages can call e.g. \`window.swarmSdk.agents.list()\`
23121
+ // directly without instantiating.
23122
+ window.SwarmSDK = SwarmSDK;
23123
+ window.swarmSdk = new SwarmSDK();
23124
+ `;
23125
+ var SWARM_UI_JS = `
23126
+ (function() {
23127
+ if (typeof window === 'undefined' || !window.customElements) return;
23128
+ if (window.customElements.get('swarm-diff')) return;
23129
+
23130
+ // Keep page-owned presence fields alongside the cursor. Room.presence.set
23131
+ // replaces its payload, so retain each room's latest page data and merge
23132
+ // the reserved __cursor field into it when the cursor moves.
23133
+ var roomPresenceTrackers = new WeakMap();
23134
+
23135
+ function clonePresenceRecord(data) {
23136
+ return data && typeof data === 'object' && !Array.isArray(data)
23137
+ ? structuredClone(data)
23138
+ : {};
23139
+ }
23140
+
23141
+ function mergeCursorPresence(data, cursor) {
23142
+ var merged = clonePresenceRecord(data);
23143
+ if (cursor) merged.__cursor = { x: cursor.x, y: cursor.y };
23144
+ else delete merged.__cursor;
23145
+ return merged;
23146
+ }
23147
+
23148
+ function trackRoomPresence(room) {
23149
+ if (!room || !room.presence || typeof room.presence.set !== 'function') return null;
23150
+ var existing = roomPresenceTrackers.get(room);
23151
+ if (existing) return existing;
23152
+
23153
+ var presence = room.presence;
23154
+ var originalSet = presence.set;
23155
+ var pageData = {};
23156
+ var cursor = null;
23157
+ var tracker = {
23158
+ setCursor: function(nextCursor) {
23159
+ cursor = nextCursor;
23160
+ return originalSet.call(presence, mergeCursorPresence(pageData, cursor));
23161
+ },
23162
+ clearCursor: function() {
23163
+ if (!cursor) return;
23164
+ return tracker.setCursor(null);
23165
+ },
23166
+ };
23167
+
23168
+ presence.set = function(data) {
23169
+ pageData = clonePresenceRecord(data);
23170
+ return originalSet.call(presence, cursor ? mergeCursorPresence(pageData, cursor) : data);
23171
+ };
23172
+ roomPresenceTrackers.set(room, tracker);
23173
+ return tracker;
23174
+ }
23175
+
23176
+ // Wrap room creation before page scripts run so presence.set calls made by
23177
+ // page code are tracked even when they happen before <swarm-cursors> connects.
23178
+ var cursorRoomRecords = new Map();
23179
+ var sdkRoomMethods = new WeakMap();
23180
+ var observedRoomClosers = new WeakSet();
23181
+ var originalRoom = null;
23182
+ function roomRecordKey(name) {
23183
+ return name === undefined ? 'default' : name;
23184
+ }
23185
+
23186
+ function observeRoom(record, room) {
23187
+ record.hasResolvedRoom = true;
23188
+ if (!cursorRoomRecords.has(record.name)) cursorRoomRecords.set(record.name, record);
23189
+ trackRoomPresence(room);
23190
+ if (room && typeof room.close === 'function' && !observedRoomClosers.has(room)) {
23191
+ var originalClose = room.close;
23192
+ room.close = function() {
23193
+ if (cursorRoomRecords.get(record.name) === record) cursorRoomRecords.delete(record.name);
23194
+ return originalClose.apply(room, arguments);
23195
+ };
23196
+ observedRoomClosers.add(room);
23197
+ }
23198
+ return room;
23199
+ }
23200
+
23201
+ function observeRoomPromise(record, result) {
23202
+ var observed = Promise.resolve(result).then(function(room) {
23203
+ var resolvedRoom = observeRoom(record, room);
23204
+ record.pageRequests--;
23205
+ record.hasPageUse = true;
23206
+ record.pageUsed = true;
23207
+ record.promise = Promise.resolve(resolvedRoom);
23208
+ return resolvedRoom;
23209
+ }).catch(function(error) {
23210
+ record.pageRequests--;
23211
+ record.pageUsed = record.hasPageUse || record.pageRequests > 0;
23212
+ if (!record.hasResolvedRoom
23213
+ && record.pageRequests === 0
23214
+ && cursorRoomRecords.get(record.name) === record)
23215
+ cursorRoomRecords.delete(record.name);
23216
+ if (record.cursorRefs === 0 && record.openedByCursor && !record.pageUsed)
23217
+ closeCursorRoomIfUnused(record);
23218
+ throw error;
23219
+ });
23220
+ record.pageRequests++;
23221
+ record.pageUsed = true;
23222
+ if (!record.promise) record.promise = observed;
23223
+ return observed;
23224
+ }
23225
+
23226
+ function closeCursorRoomIfUnused(record) {
23227
+ if (record.closing || record.cursorRefs || !record.openedByCursor || record.pageUsed) return;
23228
+ record.closing = true;
23229
+ record.promise.then(function(room) {
23230
+ if (record.cursorRefs || record.pageUsed) {
23231
+ record.closing = false;
23232
+ return;
23233
+ }
23234
+ if (cursorRoomRecords.get(record.name) === record) cursorRoomRecords.delete(record.name);
23235
+ if (room && typeof room.close === 'function') return room.close();
23236
+ }).catch(function() {
23237
+ record.closing = false;
23238
+ });
23239
+ }
23240
+
23241
+ function instrumentSdk(sdk) {
23242
+ if (!sdk || typeof sdk.room !== 'function') return null;
23243
+ var existing = sdkRoomMethods.get(sdk);
23244
+ if (existing) return existing;
23245
+
23246
+ var sdkOriginalRoom = sdk.room;
23247
+ var wrappedRoom = function(name, options) {
23248
+ var key = roomRecordKey(name);
23249
+ var record = cursorRoomRecords.get(key);
23250
+ var result = sdkOriginalRoom.call(sdk, name, options);
23251
+ if (!record) {
23252
+ record = {
23253
+ name: key,
23254
+ cursorRefs: 0,
23255
+ openedByCursor: false,
23256
+ pageUsed: false,
23257
+ hasPageUse: false,
23258
+ pageRequests: 0,
23259
+ hasResolvedRoom: false,
23260
+ promise: null,
23261
+ };
23262
+ cursorRoomRecords.set(key, record);
23263
+ }
23264
+ return observeRoomPromise(record, result);
23265
+ };
23266
+ sdk.room = wrappedRoom;
23267
+ var methods = { original: sdkOriginalRoom, wrapped: wrappedRoom };
23268
+ sdkRoomMethods.set(sdk, methods);
23269
+ return methods;
23270
+ }
23271
+
23272
+ if (window.swarmSdk) {
23273
+ var singletonRoomMethods = instrumentSdk(window.swarmSdk);
23274
+ originalRoom = singletonRoomMethods && singletonRoomMethods.original;
23275
+ }
23276
+ if (typeof window.SwarmSDK === 'function') {
23277
+ var OriginalSwarmSDK = window.SwarmSDK;
23278
+ window.SwarmSDK = new Proxy(OriginalSwarmSDK, {
23279
+ construct: function(target, args, newTarget) {
23280
+ var sdk = Reflect.construct(target, args, newTarget);
23281
+ instrumentSdk(sdk);
23282
+ return sdk;
23283
+ },
23284
+ });
23285
+ }
23286
+
23287
+ function acquireCursorRoom(name, options) {
23288
+ var key = roomRecordKey(name);
23289
+ var record = cursorRoomRecords.get(key);
23290
+ if (record) {
23291
+ record.cursorRefs++;
23292
+ return { record: record, promise: record.promise };
23293
+ }
23294
+
23295
+ record = {
23296
+ name: key,
23297
+ cursorRefs: 1,
23298
+ openedByCursor: true,
23299
+ pageUsed: false,
23300
+ hasPageUse: false,
23301
+ pageRequests: 0,
23302
+ hasResolvedRoom: false,
23303
+ closing: false,
23304
+ promise: null,
23305
+ };
23306
+ cursorRoomRecords.set(key, record);
23307
+ record.promise = Promise.resolve().then(function() {
23308
+ return originalRoom(name, options);
23309
+ }).then(function(room) {
23310
+ return observeRoom(record, room);
23311
+ }).catch(function(error) {
23312
+ if (cursorRoomRecords.get(key) === record) cursorRoomRecords.delete(key);
23313
+ throw error;
23314
+ });
23315
+ return { record: record, promise: record.promise };
23316
+ }
23317
+
23318
+ function releaseCursorRoom(record, presence) {
23319
+ if (!record || record.cursorRefs < 1) return;
23320
+ if (record.cursorRefs === 1 && presence) presence.clearCursor();
23321
+ record.cursorRefs--;
23322
+ closeCursorRoomIfUnused(record);
23323
+ }
23324
+
23325
+ var SEV_COLOR = {
23326
+ error: '#ef4444',
23327
+ warn: '#f59e0b',
23328
+ info: '#3b82f6',
23329
+ };
23330
+
23331
+ function esc(s) {
23332
+ return String(s == null ? '' : s)
23333
+ .replace(/&/g, '&amp;')
23334
+ .replace(/</g, '&lt;')
23335
+ .replace(/>/g, '&gt;')
23336
+ .replace(/"/g, '&quot;')
23337
+ .replace(/'/g, '&#39;');
23338
+ }
23339
+
23340
+ function slugifyAttr(s) {
23341
+ return String(s || '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
23342
+ }
23343
+
23344
+ function parseHunks(jsonText) {
23345
+ var trimmed = (jsonText || '').trim();
23346
+ if (!trimmed) return [];
23347
+ try {
23348
+ var parsed = JSON.parse(trimmed);
23349
+ if (parsed && Array.isArray(parsed.hunks)) return parsed.hunks;
23350
+ if (Array.isArray(parsed)) return parsed;
23351
+ return [];
23352
+ } catch (e) {
23353
+ console.warn('[swarm-diff] failed to parse JSON body:', e);
23354
+ return [];
23355
+ }
23356
+ }
23357
+
23358
+ function renderAnnotation(ann) {
23359
+ var color = SEV_COLOR[ann && ann.severity] || SEV_COLOR.info;
23360
+ return (
23361
+ '<span class="swarm-diff-annot no-print" '
23362
+ + 'style="display:inline-block;margin-left:8px;padding:1px 6px;'
23363
+ + 'border-radius:4px;font-size:11px;font-weight:600;'
23364
+ + 'background:' + color + '22;color:' + color + ';border:1px solid ' + color + '55;">'
23365
+ + esc((ann && ann.severity ? ann.severity.toUpperCase() : 'INFO')) + ' · ' + esc(ann && ann.text || '')
23366
+ + '</span>'
23367
+ );
23368
+ }
23369
+
23370
+ function renderHunk(hunk, hunkIdx, file) {
23371
+ var oldLines = hunk.old_lines || 0;
23372
+ var newLines = hunk.new_lines || 0;
23373
+ var oldStart = hunk.old_start || 0;
23374
+ var newStart = hunk.new_start || 0;
23375
+ var lines = Array.isArray(hunk.lines) ? hunk.lines : [];
23376
+ var annotations = Array.isArray(hunk.annotations) ? hunk.annotations : [];
23377
+ // Index annotations by new-side line number for fast lookup per row.
23378
+ var annByLine = {};
23379
+ for (var i = 0; i < annotations.length; i++) {
23380
+ var a = annotations[i];
23381
+ if (a && typeof a.line === 'number') {
23382
+ if (!annByLine[a.line]) annByLine[a.line] = [];
23383
+ annByLine[a.line].push(a);
23384
+ }
23385
+ }
23386
+
23387
+ var rowsHtml = '';
23388
+ var oldN = oldStart;
23389
+ var newN = newStart;
23390
+ for (var j = 0; j < lines.length; j++) {
23391
+ var line = lines[j] || {};
23392
+ var type = line.type || 'context';
23393
+ var text = line.text == null ? '' : line.text;
23394
+ var bg, oldCell, newCell, sign;
23395
+ if (type === 'add') {
23396
+ bg = 'rgba(34,197,94,0.10)';
23397
+ oldCell = '';
23398
+ newCell = String(newN++);
23399
+ sign = '+';
23400
+ } else if (type === 'del') {
23401
+ bg = 'rgba(239,68,68,0.10)';
23402
+ oldCell = String(oldN++);
23403
+ newCell = '';
23404
+ sign = '-';
23405
+ } else {
23406
+ bg = 'transparent';
23407
+ oldCell = String(oldN++);
23408
+ newCell = String(newN++);
23409
+ sign = ' ';
23410
+ }
23411
+
23412
+ var annHtml = '';
23413
+ var anns = annByLine[Number(newCell)] || annByLine[Number(oldCell)] || [];
23414
+ for (var k = 0; k < anns.length; k++) annHtml += renderAnnotation(anns[k]);
23415
+
23416
+ rowsHtml += (
23417
+ '<tr style="background:' + bg + ';">'
23418
+ + '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:#7c8aa6;font-size:12px;width:48px;">' + esc(oldCell) + '</td>'
23419
+ + '<td class="swarm-diff-gutter" style="user-select:none;text-align:right;padding:0 8px;color:#7c8aa6;font-size:12px;width:48px;">' + esc(newCell) + '</td>'
23420
+ + '<td class="swarm-diff-sign" style="user-select:none;text-align:center;padding:0 4px;color:#7c8aa6;font-size:12px;width:18px;">' + esc(sign) + '</td>'
23421
+ + '<td class="swarm-diff-code" style="padding:0 8px;white-space:pre-wrap;word-break:break-word;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:12px;">' + esc(text) + annHtml + '</td>'
23422
+ + '</tr>'
23423
+ );
23424
+ }
23425
+
23426
+ var anchorSlug = slugifyAttr((file || 'hunk') + '-' + (oldStart || hunkIdx + 1));
23427
+ var anchorId = 'swarm-diff-' + anchorSlug;
23428
+ var header = (
23429
+ '@@ -' + oldStart + ',' + oldLines + ' +' + newStart + ',' + newLines + ' @@'
23430
+ );
23431
+
23432
+ return (
23433
+ '<a id="' + esc(anchorId) + '" class="swarm-diff-anchor" data-hunk="' + esc(anchorSlug) + '"></a>'
23434
+ + '<div class="swarm-diff-hunk-header" style="padding:6px 12px;background:rgba(124,138,166,0.10);color:#7c8aa6;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:11px;border-top:1px solid var(--swarm-border,#22304a);">'
23435
+ + esc(header)
23436
+ + '</div>'
23437
+ + '<table class="swarm-diff-table" style="width:100%;border-collapse:collapse;table-layout:fixed;">'
23438
+ + '<tbody>' + rowsHtml + '</tbody>'
23439
+ + '</table>'
23440
+ );
23441
+ }
23442
+
23443
+ function renderDiff(rootEl, diffData) {
23444
+ var hunks = (diffData && Array.isArray(diffData.hunks)) ? diffData.hunks : (Array.isArray(diffData) ? diffData : []);
23445
+ var file = rootEl.getAttribute('file') || '';
23446
+ var baseSha = rootEl.getAttribute('base-sha') || '';
23447
+ var headSha = rootEl.getAttribute('head-sha') || '';
23448
+
23449
+ var shaLine = '';
23450
+ if (baseSha || headSha) {
23451
+ shaLine = '<span class="swarm-diff-sha" style="font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:11px;color:#7c8aa6;">'
23452
+ + esc(baseSha) + ' → ' + esc(headSha)
23453
+ + '</span>';
23454
+ }
23455
+
23456
+ var hunksHtml = '';
23457
+ for (var i = 0; i < hunks.length; i++) {
23458
+ hunksHtml += renderHunk(hunks[i] || {}, i, file);
23459
+ }
23460
+
23461
+ rootEl.innerHTML = (
23462
+ '<div class="swarm-diff-root" style="border:1px solid var(--swarm-border,#22304a);border-radius:8px;background:var(--swarm-card,#121826);overflow:hidden;margin:12px 0;break-inside:avoid;">'
23463
+ + '<div class="swarm-diff-header" style="display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:rgba(59,130,246,0.10);border-bottom:1px solid var(--swarm-border,#22304a);">'
23464
+ + '<span class="swarm-diff-file" style="font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:13px;font-weight:700;color:var(--swarm-text,#e6eaf2);">' + esc(file || '(untitled)') + '</span>'
23465
+ + shaLine
23466
+ + '</div>'
23467
+ + hunksHtml
23468
+ + '</div>'
23469
+ );
23470
+ }
23471
+
23472
+ // Public function form lives on window.swarmUi so callers can render an
23473
+ // arbitrary root element programmatically. The custom element below is just
23474
+ // a declarative wrapper around the same render function.
23475
+ window.swarmUi = window.swarmUi || {};
23476
+ window.swarmUi.renderDiff = renderDiff;
23477
+
23478
+ // Defer the parse-and-render so the HTML parser has time to finish
23479
+ // appending JSON text children. \`connectedCallback\` fires on the opening
23480
+ // tag — \`this.textContent\` is empty until children parse. Without a
23481
+ // defer, every declarative <swarm-diff> renders an empty header and the
23482
+ // JSON text remains visible as orphan children.
23483
+ //
23484
+ // queueMicrotask alone is NOT enough — Chrome's streaming parser drains
23485
+ // microtasks between chunks, so the microtask can run BEFORE the JSON
23486
+ // child is appended. We need to wait for the parser to finish the current
23487
+ // document load, then read textContent.
23488
+ //
23489
+ // * \`document.readyState === 'loading'\` ⇒ parser still streaming →
23490
+ // wait for DOMContentLoaded (fires after all children are parsed).
23491
+ // * otherwise (element was created/inserted dynamically post-load) ⇒
23492
+ // queueMicrotask is fine — DOM is stable, just give the caller a tick.
23493
+ //
23494
+ // Re-entrancy (element moved/reconnected) re-fires connectedCallback so
23495
+ // we re-render against current textContent.
23496
+ class SwarmDiffElement extends HTMLElement {
23497
+ connectedCallback() {
23498
+ var self = this;
23499
+ var doRender = function() {
23500
+ if (!self.isConnected) return;
23501
+ var raw = self.textContent || '';
23502
+ renderDiff(self, { hunks: parseHunks(raw) });
23503
+ // Notify <swarm-diff-jumps> instances so they can pick up new anchors.
23504
+ self.dispatchEvent(new CustomEvent('swarm-diff:rendered', { bubbles: true }));
23505
+ };
23506
+ if (typeof document !== 'undefined' && document.readyState === 'loading') {
23507
+ document.addEventListener('DOMContentLoaded', doRender, { once: true });
23508
+ } else {
23509
+ queueMicrotask(doRender);
23510
+ }
23511
+ }
23512
+ }
23513
+ window.customElements.define('swarm-diff', SwarmDiffElement);
23514
+
23515
+ // Sibling-anchor jump list. Walks subsequent siblings, finds every
23516
+ // <swarm-diff data-hunk=...> anchor, and renders a small list of links.
23517
+ //
23518
+ // Same parse-order hazard as <swarm-diff>: <swarm-diff-jumps> usually
23519
+ // appears in the document BEFORE the <swarm-diff> elements it indexes, so
23520
+ // we also defer to a microtask AND re-render whenever a <swarm-diff> in the
23521
+ // document finishes rendering its anchors.
23522
+ class SwarmDiffJumpsElement extends HTMLElement {
23523
+ connectedCallback() {
23524
+ var self = this;
23525
+ var renderJumps = function() {
23526
+ var anchors = document.querySelectorAll('.swarm-diff-anchor[data-hunk]');
23527
+ if (!anchors.length) {
23528
+ self.innerHTML = '<span class="no-print" style="color:#7c8aa6;font-size:12px;">No hunks yet.</span>';
23529
+ return;
23530
+ }
23531
+ var items = '';
23532
+ for (var i = 0; i < anchors.length; i++) {
23533
+ var a = anchors[i];
23534
+ var slug = a.getAttribute('data-hunk') || ('hunk-' + i);
23535
+ // Hunk title = nearest preceding diff's file attribute if available.
23536
+ var diff = a.closest && a.closest('swarm-diff');
23537
+ var file = (diff && diff.getAttribute('file')) || slug;
23538
+ items += '<li style="margin:0;padding:2px 0;"><a href="#' + esc(a.id) + '" style="color:#3b82f6;text-decoration:none;font-family:\\'Space Mono\\',ui-monospace,monospace;font-size:12px;">' + esc(file) + '</a></li>';
23539
+ }
23540
+ self.innerHTML = (
23541
+ '<nav class="swarm-diff-jumps no-print" style="padding:8px 12px;border:1px dashed var(--swarm-border,#22304a);border-radius:8px;background:rgba(124,138,166,0.05);">'
23542
+ + '<div style="font-size:10px;text-transform:uppercase;letter-spacing:0.08em;color:#7c8aa6;margin-bottom:4px;">Jump to</div>'
23543
+ + '<ul style="list-style:none;padding:0;margin:0;">' + items + '</ul>'
23544
+ + '</nav>'
23545
+ );
23546
+ };
23547
+ // Wait for the parser to finish initial load before first query —
23548
+ // <swarm-diff> elements also defer to DOMContentLoaded so we must
23549
+ // run AFTER they finish rendering their anchors. The event listener
23550
+ // below handles the live-update case.
23551
+ if (typeof document !== 'undefined' && document.readyState === 'loading') {
23552
+ document.addEventListener('DOMContentLoaded', function() { queueMicrotask(renderJumps); }, { once: true });
23553
+ } else {
23554
+ queueMicrotask(renderJumps);
23555
+ }
23556
+ // Re-render whenever a sibling <swarm-diff> finishes its async render.
23557
+ self._onDiffRendered = function() { renderJumps(); };
23558
+ document.addEventListener('swarm-diff:rendered', self._onDiffRendered);
23559
+ }
23560
+ disconnectedCallback() {
23561
+ if (this._onDiffRendered) {
23562
+ document.removeEventListener('swarm-diff:rendered', this._onDiffRendered);
23563
+ }
23564
+ }
23565
+ }
23566
+ window.customElements.define('swarm-diff-jumps', SwarmDiffJumpsElement);
23567
+
23568
+ var CURSOR_IDLE_MS = 3000;
23569
+ var CURSOR_SMOOTHING = 0.28;
23570
+
23571
+ function cursorColor(userId) {
23572
+ var hash = 2166136261;
23573
+ var value = String(userId || '');
23574
+ for (var i = 0; i < value.length; i++) {
23575
+ hash ^= value.charCodeAt(i);
23576
+ hash = Math.imul(hash, 16777619);
23577
+ }
23578
+ return 'hsl(' + ((hash >>> 0) % 360) + ', 72%, 42%)';
23579
+ }
23580
+
23581
+ function documentSize() {
23582
+ var root = document.documentElement || {};
23583
+ return {
23584
+ width: Math.max(1, root.scrollWidth || root.clientWidth || window.innerWidth || 1),
23585
+ height: Math.max(1, root.scrollHeight || root.clientHeight || window.innerHeight || 1),
23586
+ };
23587
+ }
23588
+
23589
+ function cursorMarkup(name, color) {
23590
+ // CursorPointer + CursorBody label structure adapted from Kibo UI (MIT):
23591
+ // https://github.com/shadcnblocks/kibo/blob/main/packages/cursor/index.tsx
23592
+ return '<svg aria-hidden="true" focusable="false" height="20" width="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" style="width:20px;height:20px;flex:none;filter:drop-shadow(0 1px 1px rgba(0,0,0,.2));">'
23593
+ + '<path d="M19.438 6.716 1.115.05A.832.832 0 0 0 .05 1.116L6.712 19.45a.834.834 0 0 0 1.557.025l3.198-8 7.995-3.2a.833.833 0 0 0 0-1.559h-.024Z" fill="currentColor"></path>'
23594
+ + '</svg>'
23595
+ + '<span style="position:relative;margin-left:14px;display:flex;flex-direction:column;white-space:nowrap;border-radius:12px;padding:4px 12px 4px 10px;font-family:system-ui,sans-serif;font-size:12px;font-weight:500;line-height:1.4;background:' + color + ';color:#fff;box-shadow:0 2px 6px rgba(0,0,0,.18);">'
23596
+ + esc(name || 'Guest')
23597
+ + '</span>';
23598
+ }
23599
+
23600
+ class SwarmCursorsElement extends HTMLElement {
23601
+ connectedCallback() {
23602
+ if (this._startPromise) return;
23603
+ var roomName = this.getAttribute('room');
23604
+ if (!roomName || !originalRoom) return;
23605
+
23606
+ var self = this;
23607
+ var lifecycle = (this._lifecycle || 0) + 1;
23608
+ this._lifecycle = lifecycle;
23609
+ var begin = function() {
23610
+ self._onDomReady = null;
23611
+ if (!self.isConnected || self._lifecycle !== lifecycle) return;
23612
+ var schemaVersion = self.getAttribute('schema-version');
23613
+ var options = schemaVersion == null ? {} : { schemaVersion: Number(schemaVersion) };
23614
+ var acquired = acquireCursorRoom(roomName, options);
23615
+ self._roomRecord = acquired.record;
23616
+ self._startPromise = acquired.promise.then(function(room) {
23617
+ if (!self.isConnected || self._lifecycle !== lifecycle) return;
23618
+ self._startPromise = null;
23619
+ self._room = room;
23620
+ self._presence = trackRoomPresence(room);
23621
+ if (!self._presence) return;
23622
+ self._pointers = new Map();
23623
+ self._cursorStates = new Map();
23624
+
23625
+ self._overlay = document.createElement('div');
23626
+ self._overlay.setAttribute('aria-hidden', 'true');
23627
+ self._overlay.style.cssText = 'position:fixed;inset:0;z-index:2147483647;pointer-events:none;overflow:hidden;';
23628
+ var parent = document.body || document.documentElement;
23629
+ if (parent) parent.appendChild(self._overlay);
23630
+
23631
+ self._onPresence = function(peers) { self._renderPeers(peers || []); };
23632
+ self._onPointerMove = function(event) {
23633
+ var size = documentSize();
23634
+ var scrollX = window.scrollX || window.pageXOffset || 0;
23635
+ var scrollY = window.scrollY || window.pageYOffset || 0;
23636
+ var pageX = typeof event.pageX === 'number' ? event.pageX : event.clientX + scrollX;
23637
+ var pageY = typeof event.pageY === 'number' ? event.pageY : event.clientY + scrollY;
23638
+ var x = Math.max(0, Math.min(1, pageX / size.width));
23639
+ var y = Math.max(0, Math.min(1, pageY / size.height));
23640
+ self._presence.setCursor({ x: x, y: y });
23641
+ };
23642
+ self._onPointerLeave = function() {
23643
+ self._presence.clearCursor();
23644
+ };
23645
+
23646
+ self._unsubscribe = room.on('presence', self._onPresence);
23647
+ document.addEventListener('pointermove', self._onPointerMove, { passive: true });
23648
+ document.addEventListener('pointerleave', self._onPointerLeave);
23649
+ self._renderPeers(room.presence.peers || []);
23650
+ }).catch(function(error) {
23651
+ self._startPromise = null;
23652
+ console.warn('[swarm-cursors] failed to join room:', error);
23653
+ });
23654
+ };
23655
+ if (document.readyState === 'loading') {
23656
+ this._onDomReady = function() { queueMicrotask(begin); };
23657
+ this._startPromise = Promise.resolve();
23658
+ document.addEventListener('DOMContentLoaded', this._onDomReady, { once: true });
23659
+ } else {
23660
+ begin();
23661
+ }
23662
+ }
23663
+
23664
+ _renderPeers(peers) {
23665
+ if (!this._pointers) return;
23666
+ var seen = new Set();
23667
+ var activePeerIds = new Set();
23668
+ var includeAgents = this.hasAttribute('include-agents');
23669
+ var ownId = this._room && this._room.me && this._room.me.userId;
23670
+ var now = Date.now();
23671
+
23672
+ for (var i = 0; i < peers.length; i++) {
23673
+ var peer = peers[i];
23674
+ if (!peer || !peer.userId || peer.userId === ownId) continue;
23675
+ if (peer.kind === 'agent' && !includeAgents) continue;
23676
+ var data = peer.data && typeof peer.data === 'object' ? peer.data : null;
23677
+ var cursor = data && data.__cursor;
23678
+ if (!cursor || typeof cursor.x !== 'number' || typeof cursor.y !== 'number'
23679
+ || !Number.isFinite(cursor.x) || !Number.isFinite(cursor.y)) continue;
23680
+
23681
+ var id = String(peer.userId);
23682
+ activePeerIds.add(id);
23683
+ var state = this._cursorStates.get(id);
23684
+ if (!state || state.x !== cursor.x || state.y !== cursor.y) {
23685
+ state = { x: cursor.x, y: cursor.y, lastSeen: now };
23686
+ this._cursorStates.set(id, state);
23687
+ }
23688
+ if (now - state.lastSeen > CURSOR_IDLE_MS) continue;
23689
+
23690
+ var entry = this._pointers.get(id);
23691
+ if (!entry) {
23692
+ entry = this._createPointer(peer);
23693
+ this._pointers.set(id, entry);
23694
+ }
23695
+ entry.cursor = { x: state.x, y: state.y };
23696
+ entry.lastSeen = state.lastSeen;
23697
+ if (entry.name !== peer.name) {
23698
+ entry.name = peer.name || 'Guest';
23699
+ entry.node.innerHTML = cursorMarkup(entry.name, entry.color);
23700
+ }
23701
+ seen.add(id);
23702
+ }
23703
+
23704
+ var ids = Array.from(this._pointers.keys());
23705
+ for (var j = 0; j < ids.length; j++) {
23706
+ if (!seen.has(ids[j])) this._removePointer(ids[j]);
23707
+ }
23708
+ var stateIds = Array.from(this._cursorStates.keys());
23709
+ for (var k = 0; k < stateIds.length; k++) {
23710
+ if (!activePeerIds.has(stateIds[k])) this._cursorStates.delete(stateIds[k]);
23711
+ }
23712
+ this._scheduleFrame();
23713
+ }
23714
+
23715
+ _createPointer(peer) {
23716
+ var color = cursorColor(peer.userId);
23717
+ var node = document.createElement('div');
23718
+ node.style.cssText = 'position:absolute;left:0;top:0;display:flex;align-items:flex-start;pointer-events:none;user-select:none;will-change:transform;color:' + color + ';';
23719
+ node.innerHTML = cursorMarkup(peer.name || 'Guest', color);
23720
+ this._overlay.appendChild(node);
23721
+ return {
23722
+ node: node,
23723
+ color: color,
23724
+ name: peer.name || 'Guest',
23725
+ cursor: null,
23726
+ x: null,
23727
+ y: null,
23728
+ lastSeen: Date.now(),
23729
+ };
23730
+ }
23731
+
23732
+ _removePointer(id) {
23733
+ var entry = this._pointers.get(id);
23734
+ if (entry && entry.node.parentNode) entry.node.parentNode.removeChild(entry.node);
23735
+ this._pointers.delete(id);
23736
+ }
23737
+
23738
+ _scheduleFrame() {
23739
+ if (this._frameId != null || !this._pointers || !this._pointers.size
23740
+ || typeof window.requestAnimationFrame !== 'function') return;
23741
+ var self = this;
23742
+ this._frameId = window.requestAnimationFrame(function() { self._animate(); });
23743
+ }
23744
+
23745
+ _animate() {
23746
+ this._frameId = null;
23747
+ if (!this._pointers || !this._overlay) return;
23748
+ var now = Date.now();
23749
+ var size = documentSize();
23750
+ var scrollX = window.scrollX || window.pageXOffset || 0;
23751
+ var scrollY = window.scrollY || window.pageYOffset || 0;
23752
+ var ids = Array.from(this._pointers.keys());
23753
+
23754
+ for (var i = 0; i < ids.length; i++) {
23755
+ var id = ids[i];
23756
+ var entry = this._pointers.get(id);
23757
+ if (now - entry.lastSeen > CURSOR_IDLE_MS) {
23758
+ this._removePointer(id);
23759
+ continue;
23760
+ }
23761
+ var targetX = entry.cursor.x * size.width - scrollX;
23762
+ var targetY = entry.cursor.y * size.height - scrollY;
23763
+ if (entry.x == null || entry.y == null) {
23764
+ entry.x = targetX;
23765
+ entry.y = targetY;
23766
+ } else {
23767
+ // Exponential interpolation keeps 50 ms presence updates from jumping.
23768
+ entry.x += (targetX - entry.x) * CURSOR_SMOOTHING;
23769
+ entry.y += (targetY - entry.y) * CURSOR_SMOOTHING;
23770
+ }
23771
+ entry.node.style.transform = 'translate3d(' + Math.round(entry.x) + 'px,' + Math.round(entry.y) + 'px,0)';
23772
+ }
23773
+ this._scheduleFrame();
23774
+ }
23775
+
23776
+ disconnectedCallback() {
23777
+ this._lifecycle = (this._lifecycle || 0) + 1;
23778
+ this._startPromise = null;
23779
+ if (this._onDomReady) {
23780
+ document.removeEventListener('DOMContentLoaded', this._onDomReady);
23781
+ this._onDomReady = null;
23782
+ }
23783
+ if (this._unsubscribe) this._unsubscribe();
23784
+ if (this._onPointerMove) document.removeEventListener('pointermove', this._onPointerMove);
23785
+ if (this._onPointerLeave) document.removeEventListener('pointerleave', this._onPointerLeave);
23786
+ if (this._roomRecord) releaseCursorRoom(this._roomRecord, this._presence);
23787
+ if (this._frameId != null && typeof window.cancelAnimationFrame === 'function')
23788
+ window.cancelAnimationFrame(this._frameId);
23789
+ if (this._pointers) {
23790
+ var ids = Array.from(this._pointers.keys());
23791
+ for (var i = 0; i < ids.length; i++) this._removePointer(ids[i]);
23792
+ }
23793
+ if (this._overlay && this._overlay.parentNode)
23794
+ this._overlay.parentNode.removeChild(this._overlay);
23795
+ this._room = null;
23796
+ this._roomRecord = null;
23797
+ this._presence = null;
23798
+ this._overlay = null;
23799
+ this._pointers = null;
23800
+ this._cursorStates = null;
23801
+ this._frameId = null;
23802
+ }
23803
+ }
23804
+ window.customElements.define('swarm-cursors', SwarmCursorsElement);
23805
+ })();
23806
+ `;
23807
+
23808
+ // src/pages/feedback-overlay.ts
22640
23809
  var PAGE_FEEDBACK_PARAM = "__swarm-feedback";
22641
23810
  function isPageFeedbackRequested(queryParams) {
22642
23811
  if (!queryParams.has(PAGE_FEEDBACK_PARAM))
@@ -23141,7 +24310,6 @@ function feedbackOverlayScripts(pageId) {
23141
24310
  }
23142
24311
 
23143
24312
  // src/http/pages-public.ts
23144
- init_db3();
23145
24313
  init_types();
23146
24314
  init_constants();
23147
24315
  init_node_env();
@@ -23709,21 +24877,11 @@ var PollTriggerAttachmentSchema = TaskAttachmentSchema.pick({
23709
24877
  mimeType: true,
23710
24878
  sizeBytes: true
23711
24879
  });
23712
- var PollRequestedBySchema = UserSchema.pick({
23713
- id: true,
23714
- name: true,
23715
- email: true,
23716
- role: true,
23717
- notes: true
23718
- }).extend({
23719
- id: exports_external.string().optional(),
23720
- comms: UserCommsPrefsSchema.optional()
23721
- });
23722
24880
  var PollTaskOfferedTriggerSchema = exports_external.object({
23723
24881
  type: exports_external.literal("task_offered"),
23724
24882
  taskId: exports_external.string(),
23725
24883
  task: AgentTaskSchema,
23726
- requestedBy: PollRequestedBySchema.optional()
24884
+ requestedBy: TaskRequestedBySchema.optional()
23727
24885
  });
23728
24886
  var PollTaskAssignedTriggerSchema = exports_external.object({
23729
24887
  type: exports_external.literal("task_assigned"),
@@ -23732,7 +24890,7 @@ var PollTaskAssignedTriggerSchema = exports_external.object({
23732
24890
  task: AgentTaskSchema.extend({
23733
24891
  attachments: exports_external.array(PollTriggerAttachmentSchema)
23734
24892
  }),
23735
- requestedBy: PollRequestedBySchema.optional()
24893
+ requestedBy: TaskRequestedBySchema.optional()
23736
24894
  });
23737
24895
  var PollUnreadMentionsTriggerSchema = exports_external.object({
23738
24896
  type: exports_external.literal("unread_mentions"),
@@ -23780,26 +24938,6 @@ var pollTriggers = route({
23780
24938
  });
23781
24939
  var CHANNEL_ACTIVITY_INTERVAL_MS = 60000;
23782
24940
  var lastChannelActivityCheckAt = 0;
23783
- function getRequesterNotes(notes) {
23784
- return typeof notes === "string" && notes.trim().length > 0 ? notes : undefined;
23785
- }
23786
- async function buildTriggerRequestedBy(task) {
23787
- const user = task.requestedByUserId ? await getUserById(task.requestedByUserId) : undefined;
23788
- if (user) {
23789
- return {
23790
- id: user.id,
23791
- name: user.name,
23792
- email: user.email,
23793
- role: user.role,
23794
- notes: getRequesterNotes(user.notes),
23795
- comms: getUserCommsPrefs(user)
23796
- };
23797
- }
23798
- if (task.slackUserId) {
23799
- return { name: renderIdentity(await resolveIdentity("slack", task.slackUserId)) };
23800
- }
23801
- return;
23802
- }
23803
24941
  async function attachmentsForTrigger(taskId) {
23804
24942
  return (await getTaskAttachments(taskId)).map((a) => ({
23805
24943
  id: a.id,
@@ -23809,11 +24947,21 @@ async function attachmentsForTrigger(taskId) {
23809
24947
  }));
23810
24948
  }
23811
24949
  async function claimModelFields(task, agent) {
24950
+ const pin = taskModelPin(task);
24951
+ const cleared = {
24952
+ model: pin,
24953
+ resolvedModel: undefined,
24954
+ modelSource: undefined,
24955
+ modelAlias: undefined
24956
+ };
23812
24957
  try {
23813
- return await recordClaimModelResolution(task, agent);
24958
+ return {
24959
+ ...cleared,
24960
+ ...await recordClaimModelResolution({ ...task, model: pin }, agent)
24961
+ };
23814
24962
  } catch (error) {
23815
24963
  console.warn(`[/api/poll] model resolution failed for task ${task.id}:`, error);
23816
- return {};
24964
+ return cleared;
23817
24965
  }
23818
24966
  }
23819
24967
  var commitCursorsRoute = route({
@@ -23898,7 +25046,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
23898
25046
  const claimedTask = await claimOfferedTask(firstOfferedTask.id, myAgentId);
23899
25047
  if (claimedTask) {
23900
25048
  await recordRuntimeTask(claimedTask.id);
23901
- const offeredRequestedBy = await buildTriggerRequestedBy(claimedTask);
25049
+ const offeredRequestedBy = await buildTaskRequestedBy(claimedTask);
23902
25050
  return {
23903
25051
  trigger: {
23904
25052
  type: "task_offered",
@@ -23978,7 +25126,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
23978
25126
  agentId: myAgentId
23979
25127
  });
23980
25128
  });
23981
- const assignedRequestedBy = await buildTriggerRequestedBy(pendingTask);
25129
+ const assignedRequestedBy = await buildTaskRequestedBy(pendingTask);
23982
25130
  const assignedTriggerSurface = await resolveTriggerSurface(pendingTask.id, pendingTask.source);
23983
25131
  return {
23984
25132
  trigger: {
@@ -24069,7 +25217,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
24069
25217
  agentId: myAgentId
24070
25218
  });
24071
25219
  });
24072
- const claimedRequestedBy = await buildTriggerRequestedBy(claimed);
25220
+ const claimedRequestedBy = await buildTaskRequestedBy(claimed);
24073
25221
  const claimedTriggerSurface = await resolveTriggerSurface(claimed.id, claimed.source);
24074
25222
  return {
24075
25223
  trigger: {
@@ -29605,6 +30753,7 @@ async function handleScripts(req, res, pathSegments, queryParams, agentId) {
29605
30753
  runtimeInstanceId,
29606
30754
  egressSecrets: credentials.egressSecrets,
29607
30755
  failedBindings: credentials.failedBindings,
30756
+ userConfig: credentials.userConfig,
29608
30757
  apiConnections: getScriptApiConnectionDescriptors({ agentId: agent.id }),
29609
30758
  mcpConnections: getScriptMcpConnectionDescriptors({ agentId: agent.id })
29610
30759
  });
@@ -32101,21 +33250,6 @@ var getMetrics = route({
32101
33250
  200: { description: "Swarm metrics counts", schema: SwarmMetricsSchema }
32102
33251
  }
32103
33252
  });
32104
- var listServices = route({
32105
- method: "get",
32106
- path: "/api/services",
32107
- pattern: ["api", "services"],
32108
- summary: "List all registered services",
32109
- tags: ["Stats"],
32110
- query: exports_external.object({
32111
- status: exports_external.string().optional(),
32112
- agentId: exports_external.string().optional(),
32113
- name: exports_external.string().optional()
32114
- }),
32115
- responses: {
32116
- 200: { description: "Service list", schema: exports_external.object({ services: exports_external.array(ServiceSchema) }) }
32117
- }
32118
- });
32119
33253
  var listScheduledTasks = route({
32120
33254
  method: "get",
32121
33255
  path: "/api/scheduled-tasks",
@@ -32201,18 +33335,6 @@ async function handleStats(req, res, pathSegments, queryParams, myAgentId) {
32201
33335
  });
32202
33336
  return true;
32203
33337
  }
32204
- if (listServices.match(req.method, pathSegments)) {
32205
- const parsed = await listServices.parse(req, res, pathSegments, queryParams);
32206
- if (!parsed)
32207
- return true;
32208
- const services = await getAllServices({
32209
- status: parsed.query.status || undefined,
32210
- agentId: parsed.query.agentId || undefined,
32211
- name: parsed.query.name || undefined
32212
- });
32213
- listServices.respond(res, 200, { services });
32214
- return true;
32215
- }
32216
33338
  if (listScheduledTasks.match(req.method, pathSegments)) {
32217
33339
  const parsed = await listScheduledTasks.parse(req, res, pathSegments, queryParams);
32218
33340
  if (!parsed)
@@ -34358,6 +35480,8 @@ async function routeKapsoInbound(payload) {
34358
35480
  }
34359
35481
 
34360
35482
  // src/http/webhooks.ts
35483
+ init_constants();
35484
+ init_secret_scrubber();
34361
35485
  init_event_bus();
34362
35486
  var WebhookDispatchResultSchema = exports_external.object({
34363
35487
  created: exports_external.boolean(),
@@ -34453,6 +35577,57 @@ var kapsoWebhook = route({
34453
35577
  503: { description: "Kapso integration not configured" }
34454
35578
  }
34455
35579
  });
35580
+ var chatSdkWebhook = route({
35581
+ method: "post",
35582
+ path: "/api/integrations/chat/{adapter}/webhook",
35583
+ pattern: ["api", "integrations", "chat", null, "webhook"],
35584
+ summary: "Handle Chat SDK platform webhooks (Telegram, Slack, Discord, Teams)",
35585
+ tags: ["Webhooks"],
35586
+ params: exports_external.object({ adapter: exports_external.string().describe("Chat SDK adapter name, e.g. telegram") }),
35587
+ auth: { apiKey: false },
35588
+ rbac: {
35589
+ ungated: "provider webhook: the Chat SDK adapter verifies the platform signature (Telegram secret token, Slack signing secret, Discord Ed25519, Teams JWT)"
35590
+ },
35591
+ responses: {
35592
+ 200: { description: "Adapter response", unstructured: "adapter response proxied as-is" },
35593
+ 401: { description: "Invalid platform signature or secret token" },
35594
+ 403: { description: "Teams activity whose serviceUrl is not a Bot Framework host" },
35595
+ 404: { description: "Chat SDK disabled or adapter not configured" },
35596
+ 413: { description: "Body exceeds 1 MiB" },
35597
+ 503: { description: "Adapter configured but failed to start" }
35598
+ }
35599
+ });
35600
+ var CHAT_SDK_WEBHOOK_MAX_BODY_BYTES = 1024 * 1024;
35601
+ function hasTrustedTeamsServiceUrl(body) {
35602
+ let serviceUrl;
35603
+ try {
35604
+ serviceUrl = JSON.parse(body.toString("utf-8"))?.serviceUrl;
35605
+ } catch {
35606
+ return true;
35607
+ }
35608
+ if (serviceUrl === undefined || serviceUrl === null || serviceUrl === "")
35609
+ return true;
35610
+ return typeof serviceUrl === "string" && isTrustedTeamsServiceUrl(serviceUrl);
35611
+ }
35612
+ function toFetchRequest(req, rawBody, fallbackPath) {
35613
+ const headers2 = new Headers;
35614
+ if (Array.isArray(req.rawHeaders) && req.rawHeaders.length > 0) {
35615
+ for (let i = 0;i + 1 < req.rawHeaders.length; i += 2) {
35616
+ headers2.append(req.rawHeaders[i], req.rawHeaders[i + 1]);
35617
+ }
35618
+ } else {
35619
+ for (const [name, value] of Object.entries(req.headers)) {
35620
+ for (const item of Array.isArray(value) ? value : value === undefined ? [] : [value]) {
35621
+ headers2.append(name, item);
35622
+ }
35623
+ }
35624
+ }
35625
+ return new Request(`${getPublicMcpBaseUrl()}${req.url ?? fallbackPath}`, {
35626
+ method: req.method ?? "POST",
35627
+ headers: headers2,
35628
+ body: rawBody.length > 0 ? new Uint8Array(rawBody) : undefined
35629
+ });
35630
+ }
34456
35631
  function logKapsoAckResult(action, result) {
34457
35632
  if (result.ok)
34458
35633
  return;
@@ -34536,7 +35711,8 @@ async function handleWebhooks(req, res, pathSegments) {
34536
35711
  res.end(JSON.stringify({ error: "Invalid JSON body" }));
34537
35712
  return true;
34538
35713
  }
34539
- console.log(`[GitHub] Received ${eventType} event`);
35714
+ const deliveryId = req.headers["x-github-delivery"];
35715
+ console.log(`[GitHub] Received ${eventType} event (delivery ${deliveryId ?? "unknown"})`);
34540
35716
  let result = { created: false };
34541
35717
  try {
34542
35718
  result = await runBlockableHandler("GitHub", async () => {
@@ -34610,13 +35786,13 @@ async function handleWebhooks(req, res, pathSegments) {
34610
35786
  }
34611
35787
  githubWebhook.respond(res, 200, result);
34612
35788
  } catch (err) {
34613
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34614
- console.error(`[GitHub] Error handling ${eventType} event: ${errorMessage2}`);
35789
+ const errorMessage3 = err instanceof Error ? err.message : String(err);
35790
+ console.error(`[GitHub] Error handling ${eventType} event: ${errorMessage3}`);
34615
35791
  if (err instanceof Error && err.stack) {
34616
35792
  console.error(err.stack);
34617
35793
  }
34618
35794
  res.writeHead(500, { "Content-Type": "application/json" });
34619
- res.end(JSON.stringify({ error: "Internal server error", message: errorMessage2 }));
35795
+ res.end(JSON.stringify({ error: "Internal server error", message: errorMessage3 }));
34620
35796
  }
34621
35797
  return true;
34622
35798
  }
@@ -34724,8 +35900,8 @@ async function handleWebhooks(req, res, pathSegments) {
34724
35900
  }
34725
35901
  gitlabWebhook.respond(res, 200, result);
34726
35902
  } catch (err) {
34727
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34728
- console.error(`[GitLab] Error handling ${objectKind} event: ${errorMessage2}`);
35903
+ const errorMessage3 = err instanceof Error ? err.message : String(err);
35904
+ console.error(`[GitLab] Error handling ${objectKind} event: ${errorMessage3}`);
34729
35905
  if (err instanceof Error && err.stack) {
34730
35906
  console.error(err.stack);
34731
35907
  }
@@ -34815,8 +35991,8 @@ async function handleWebhooks(req, res, pathSegments) {
34815
35991
  }
34816
35992
  azureDevOpsWebhook.respond(res, 200, result);
34817
35993
  } catch (err) {
34818
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34819
- console.error(`[AzureDevOps] Error handling ${eventType} event: ${errorMessage2}`);
35994
+ const errorMessage3 = err instanceof Error ? err.message : String(err);
35995
+ console.error(`[AzureDevOps] Error handling ${eventType} event: ${errorMessage3}`);
34820
35996
  if (err instanceof Error && err.stack) {
34821
35997
  console.error(err.stack);
34822
35998
  }
@@ -34884,8 +36060,8 @@ async function handleWebhooks(req, res, pathSegments) {
34884
36060
  console.log(`[AgentMail] Ignoring event type: ${payload.event_type}`);
34885
36061
  }
34886
36062
  } catch (err) {
34887
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34888
- console.error(`[AgentMail] Error handling ${payload.event_type} event: ${errorMessage2}`);
36063
+ const errorMessage3 = err instanceof Error ? err.message : String(err);
36064
+ console.error(`[AgentMail] Error handling ${payload.event_type} event: ${errorMessage3}`);
34889
36065
  if (err instanceof Error && err.stack) {
34890
36066
  console.error(err.stack);
34891
36067
  }
@@ -34945,16 +36121,84 @@ async function handleWebhooks(req, res, pathSegments) {
34945
36121
  }
34946
36122
  kapsoWebhook.respond(res, 200, { received: true, routing: routing.kind });
34947
36123
  } catch (err) {
34948
- const errorMessage2 = err instanceof Error ? err.message : String(err);
36124
+ const errorMessage3 = err instanceof Error ? err.message : String(err);
34949
36125
  if (err instanceof WebhookError) {
34950
- console.warn(`[Kapso] Workflow dispatch rejected: ${errorMessage2}`);
36126
+ console.warn(`[Kapso] Workflow dispatch rejected: ${errorMessage3}`);
34951
36127
  } else {
34952
- console.error(`[Kapso] Error handling inbound event: ${errorMessage2}`);
36128
+ console.error(`[Kapso] Error handling inbound event: ${errorMessage3}`);
34953
36129
  }
34954
36130
  kapsoWebhook.respond(res, 200, { received: true, routing: "error" });
34955
36131
  }
34956
36132
  return true;
34957
36133
  }
36134
+ if (chatSdkWebhook.match(req.method, pathSegments)) {
36135
+ const adapterName = pathSegments[3] ?? "";
36136
+ if (!isChatSdkEnabled() || !isChatAdapterConfigured(adapterName)) {
36137
+ res.writeHead(404, { "Content-Type": "application/json" });
36138
+ res.end(JSON.stringify({ error: "Chat SDK adapter not configured" }));
36139
+ return true;
36140
+ }
36141
+ if (isChatSdkStopping()) {
36142
+ res.writeHead(503, { "Content-Type": "application/json" });
36143
+ res.end(JSON.stringify({ error: "Chat SDK is shutting down" }));
36144
+ return true;
36145
+ }
36146
+ const chat = getChatInstance(adapterName);
36147
+ const handler = chat?.webhooks[adapterName];
36148
+ if (!handler) {
36149
+ res.writeHead(503, { "Content-Type": "application/json" });
36150
+ res.end(JSON.stringify({ error: "Chat SDK adapter failed to start" }));
36151
+ return true;
36152
+ }
36153
+ if (enforceContentLengthCap(req, res, CHAT_SDK_WEBHOOK_MAX_BODY_BYTES) === BODY_TOO_LARGE) {
36154
+ return true;
36155
+ }
36156
+ const chunks = [];
36157
+ let receivedBytes = 0;
36158
+ let tooLarge = false;
36159
+ for await (const chunk of req) {
36160
+ if (tooLarge)
36161
+ continue;
36162
+ receivedBytes += chunk.byteLength;
36163
+ if (receivedBytes > CHAT_SDK_WEBHOOK_MAX_BODY_BYTES) {
36164
+ tooLarge = true;
36165
+ chunks.length = 0;
36166
+ jsonError(res, `Payload too large (max ${CHAT_SDK_WEBHOOK_MAX_BODY_BYTES} bytes)`, 413);
36167
+ continue;
36168
+ }
36169
+ chunks.push(chunk);
36170
+ }
36171
+ if (tooLarge)
36172
+ return true;
36173
+ const rawBody = Buffer.concat(chunks);
36174
+ if (adapterName === "teams" && !hasTrustedTeamsServiceUrl(rawBody)) {
36175
+ console.warn("[chat-sdk] teams webhook refused: serviceUrl is not a Bot Framework host");
36176
+ res.writeHead(403, { "Content-Type": "application/json" });
36177
+ res.end(JSON.stringify({ error: "Untrusted Teams serviceUrl" }));
36178
+ return true;
36179
+ }
36180
+ const request = toFetchRequest(req, rawBody, `/api/integrations/chat/${adapterName}/webhook`);
36181
+ try {
36182
+ const response = await handler(request, {
36183
+ waitUntil: trackBackground
36184
+ });
36185
+ const responseHeaders = {};
36186
+ response.headers.forEach((value, name) => {
36187
+ responseHeaders[name] = value;
36188
+ });
36189
+ const body = Buffer.from(await response.arrayBuffer());
36190
+ res.writeHead(response.status, responseHeaders);
36191
+ res.end(body);
36192
+ } catch (err) {
36193
+ const message = err instanceof Error ? err.message : String(err);
36194
+ console.error(`[chat-sdk] ${adapterName} webhook failed: ${scrubSecrets(message)}`);
36195
+ if (!res.headersSent) {
36196
+ res.writeHead(500, { "Content-Type": "application/json" });
36197
+ }
36198
+ res.end(JSON.stringify({ error: "Chat SDK webhook failed" }));
36199
+ }
36200
+ return true;
36201
+ }
34958
36202
  return false;
34959
36203
  }
34960
36204
 
@@ -35977,6 +37221,7 @@ async function handleX(req, res, pathSegments) {
35977
37221
  timeoutMs,
35978
37222
  egressSecrets: credentials.egressSecrets,
35979
37223
  failedBindings: credentials.failedBindings,
37224
+ userConfig: credentials.userConfig,
35980
37225
  apiConnections: getScriptApiConnectionDescriptors({ agentId: endpoint.agentId }),
35981
37226
  mcpConnections: getScriptMcpConnectionDescriptors({ agentId: endpoint.agentId })
35982
37227
  });
@@ -36125,7 +37370,6 @@ var httpServer = createHttpServer(async (req, res) => {
36125
37370
  () => handleAgentRegister(req, res, pathSegments, myAgentId),
36126
37371
  () => handlePoll(req, res, pathSegments, queryParams, myAgentId),
36127
37372
  () => handleSessionData(req, res, pathSegments, queryParams, myAgentId),
36128
- () => handleEcosystem(req, res, pathSegments, myAgentId),
36129
37373
  () => handleTrackers(req, res, pathSegments),
36130
37374
  () => handleWebhooks(req, res, pathSegments),
36131
37375
  () => handleAgentsRest(req, res, pathSegments, queryParams, myAgentId),
@@ -36217,7 +37461,7 @@ var httpServer = createHttpServer(async (req, res) => {
36217
37461
  });
36218
37462
  });
36219
37463
  var detachRealtime = attachRealtimeTransport(httpServer);
36220
- var { attachControllerTransport } = await import("./controllers-connect-3mf2btyj.js");
37464
+ var { attachControllerTransport } = await import("./controllers-connect-kwpvj3rf.js");
36221
37465
  var detachControllers = attachControllerTransport(httpServer);
36222
37466
  var stopWorkerNudges = startWorkerNudgeListener();
36223
37467
  var stopRoomDeletion = realtimeBus.subscribe("room:namespace-deleted", (namespace) => {
@@ -36246,7 +37490,7 @@ async function shutdown() {
36246
37490
  sessionsProcessed: getServerSessionsProcessed()
36247
37491
  });
36248
37492
  if (hasCapability("scheduling")) {
36249
- const { stopScheduler } = await import("./index-fx3jqq1e.js");
37493
+ const { stopScheduler } = await import("./index-7ep4gzdk.js");
36250
37494
  stopScheduler();
36251
37495
  }
36252
37496
  stopHeartbeat();
@@ -36256,8 +37500,9 @@ async function shutdown() {
36256
37500
  await drainApi();
36257
37501
  await stopScriptRunSupervisor();
36258
37502
  await stopSlackApp();
37503
+ await stopChatSdk();
36259
37504
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
36260
- const { stopOAuthKeepalive } = await import("./keepalive-6ywhpja1.js");
37505
+ const { stopOAuthKeepalive } = await import("./keepalive-be9vwy5h.js");
36261
37506
  await stopOAuthKeepalive();
36262
37507
  }
36263
37508
  stopOAuthPendingGc();
@@ -36337,15 +37582,15 @@ try {
36337
37582
  console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
36338
37583
  }
36339
37584
  try {
36340
- const { ensurePricingSeeded } = await import("./boot-seeds-d8sp49t2.js");
37585
+ const { ensurePricingSeeded } = await import("./boot-seeds-kwjq4d2z.js");
36341
37586
  ensurePricingSeeded();
36342
- const { startPricingRefreshLoop } = await import("./pricing-refresh-gedkjdw0.js");
37587
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-qb0rv0ap.js");
36343
37588
  startPricingRefreshLoop();
36344
37589
  } catch (err) {
36345
37590
  console.error("[startup] Failed to seed pricing rows:", err);
36346
37591
  }
36347
37592
  try {
36348
- const { ensureRbacSeeded } = await import("./boot-seeds-d8sp49t2.js");
37593
+ const { ensureRbacSeeded } = await import("./boot-seeds-kwjq4d2z.js");
36349
37594
  ensureRbacSeeded();
36350
37595
  } catch (err) {
36351
37596
  console.error("[startup] Failed to sync RBAC seed rows:", err);
@@ -36353,7 +37598,7 @@ try {
36353
37598
  throw err;
36354
37599
  }
36355
37600
  try {
36356
- const { runAllSeeders } = await import("./index-2ybk7khy.js");
37601
+ const { runAllSeeders } = await import("./index-s2wxgzr0.js");
36357
37602
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
36358
37603
  } catch (err) {
36359
37604
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -36401,6 +37646,9 @@ httpServer.listen(port, async () => {
36401
37646
  } catch (err) {
36402
37647
  console.error("[Slack] Failed to start, continuing boot without Slack:", err);
36403
37648
  }
37649
+ startChatSdk().catch((err) => {
37650
+ console.error("[chat-sdk] Failed to start, continuing without Chat SDK:", scrubSecrets(err instanceof Error ? err.message : String(err)));
37651
+ });
36404
37652
  startQueueStallAlarm();
36405
37653
  initGitHub();
36406
37654
  initGitLab();
@@ -36411,39 +37659,39 @@ httpServer.listen(port, async () => {
36411
37659
  await initWorkflows();
36412
37660
  await startScriptRunSupervisor(getMcpBaseUrl());
36413
37661
  if (hasCapability("scheduling")) {
36414
- const { startScheduler } = await import("./index-fx3jqq1e.js");
36415
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-g2byveez.js");
37662
+ const { startScheduler } = await import("./index-7ep4gzdk.js");
37663
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-rmpw9a8q.js");
36416
37664
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
36417
37665
  startScheduler(getExecutorRegistry2(), intervalMs, {
36418
37666
  runId: globalState.__runId
36419
37667
  });
36420
37668
  }
36421
37669
  if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
36422
- const { startHeartbeat } = await import("./index-bdsqa799.js");
37670
+ const { startHeartbeat } = await import("./index-v1v6n7hg.js");
36423
37671
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
36424
37672
  startHeartbeat(heartbeatMs);
36425
37673
  }
36426
37674
  startPoolRouting();
36427
37675
  startRuntimeSupervisor();
36428
37676
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
36429
- const { startOAuthKeepalive } = await import("./keepalive-6ywhpja1.js");
37677
+ const { startOAuthKeepalive } = await import("./keepalive-be9vwy5h.js");
36430
37678
  startOAuthKeepalive();
36431
37679
  }
36432
37680
  if (process.env.OAUTH_REFRESH_SWEEP_DISABLE !== "true") {
36433
- const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-3c6f8vyy.js");
37681
+ const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-cpdnfwdj.js");
36434
37682
  startOAuthRefreshSweep();
36435
37683
  }
36436
37684
  startOAuthPendingGc();
36437
37685
  await startMemoryGc();
36438
37686
  await startDbRetention();
36439
37687
  startHumanFreeDrain();
36440
- import("./boot-reembed-swwzdgd7.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
37688
+ import("./boot-reembed-5c2z0mbe.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
36441
37689
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
36442
37690
  });
36443
- import("./boot-reembed-16rv9843.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
37691
+ import("./boot-reembed-j8xa181e.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
36444
37692
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
36445
37693
  });
36446
- import("./boot-scrub-sweep-zkr6vkqb.js").then(({ runBootScrubSweep }) => runBootScrubSweep()).catch((err) => {
37694
+ import("./boot-scrub-sweep-hnkn3rgt.js").then(({ runBootScrubSweep }) => runBootScrubSweep()).catch((err) => {
36447
37695
  console.error("[boot-scrub-sweep] startup scrub failed (non-fatal):", err);
36448
37696
  });
36449
37697
  }).on("error", (err) => {