@desplega.ai/agent-swarm 1.172.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 (525) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-fpecx1g1.js → acp-adapter-sj2g0m84.js} +18 -17
  3. package/dist/{actions-pw87a1a8.js → actions-fegk44gr.js} +65 -35
  4. package/dist/{amp-adapter-8jem2bc0.js → amp-adapter-ad8ft89x.js} +8 -7
  5. package/dist/{anthropic-messages-8ee2f22q.js → anthropic-messages-r6czkjv1.js} +7 -7
  6. package/dist/{app-wmf0m843.js → app-kfvgbvzy.js} +19 -13
  7. package/dist/{assistant-emp1e108.js → assistant-z7zdy9ja.js} +65 -38
  8. package/dist/{boot-reembed-1de4f4aj.js → boot-reembed-5c2z0mbe.js} +11 -9
  9. package/dist/{boot-reembed-4ymn9atn.js → boot-reembed-j8xa181e.js} +11 -9
  10. package/dist/{boot-scrub-sweep-adhk1s8c.js → boot-scrub-sweep-hnkn3rgt.js} +12 -10
  11. package/dist/{boot-seeds-8q637aew.js → boot-seeds-kwjq4d2z.js} +15 -13
  12. package/dist/{claude-adapter-t26cv8a4.js → claude-adapter-9vmvpvgd.js} +20 -19
  13. package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-k9qae05j.js} +7 -5
  14. package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-q54zx5q2.js} +6 -4
  15. package/dist/{claude-sdk-session-gsfsh662.js → claude-sdk-session-9jye6cxr.js} +12698 -11995
  16. package/dist/{cli-k46r9hmk.js → cli-03gedhng.js} +16 -14
  17. package/dist/{cli-kb4ehzx5.js → cli-1e4b6bzh.js} +7 -7
  18. package/dist/{cli-d603qf86.js → cli-29jc5q7w.js} +10 -8
  19. package/dist/cli-2m1ktfzz.js +17795 -0
  20. package/dist/{cli-8vs9trd4.js → cli-3dj8k4vy.js} +1 -1
  21. package/dist/{cli-zxm9p3x4.js → cli-3fbmmawm.js} +5 -5
  22. package/dist/{cli-gmdajfw5.js → cli-4jxm2qtz.js} +4987 -1708
  23. package/dist/{cli-tadfgd0t.js → cli-5hkm7whv.js} +33 -4
  24. package/dist/{cli-6jb2rf77.js → cli-5t4f29ez.js} +3 -3
  25. package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
  26. package/dist/cli-6cvfxs8r.js +47 -0
  27. package/dist/{cli-pj6x9qce.js → cli-6jyj59nb.js} +2 -2
  28. package/dist/{cli-388egyf6.js → cli-6razj6t4.js} +2 -2
  29. package/dist/{cli-qsztpfry.js → cli-74ahz61x.js} +2 -2
  30. package/dist/{cli-4nz8p1p5.js → cli-7x0g4sn1.js} +15474 -16082
  31. package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
  32. package/dist/{cli-81r1wjyv.js → cli-9nfx44eh.js} +1 -1
  33. package/dist/cli-9traj3dn.js +638 -0
  34. package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
  35. package/dist/{cli-bf7485pm.js → cli-apx87jne.js} +2 -2
  36. package/dist/{cli-ztrv9y21.js → cli-bzszjf2p.js} +3689 -1081
  37. package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
  38. package/dist/{cli-hsem16hb.js → cli-cgtksawx.js} +7 -4
  39. package/dist/{cli-db3m6zdt.js → cli-d2qr7aj4.js} +1 -1
  40. package/dist/{cli-1hgat6pa.js → cli-d5f9ed5c.js} +5 -5
  41. package/dist/cli-e3g5mbkz.js +776 -0
  42. package/dist/{cli-7jykv7ef.js → cli-e6mpjhed.js} +1 -1
  43. package/dist/{cli-j6kpj9az.js → cli-ee9gtz70.js} +1553 -68
  44. package/dist/{cli-e0a9sk00.js → cli-eejsgvm4.js} +4 -4
  45. package/dist/{cli-tgpfnm6r.js → cli-ef1hg1wv.js} +518 -59
  46. package/dist/cli-f527ce74.js +781 -0
  47. package/dist/{cli-ppy4nnnh.js → cli-f7kr7svz.js} +2 -2
  48. package/dist/cli-hjwmhcg1.js +10622 -0
  49. package/dist/{cli-2bw3w47j.js → cli-hnhtk6cj.js} +1 -1
  50. package/dist/{cli-ywm1azg9.js → cli-hnmhtzvh.js} +6 -4
  51. package/dist/{cli-4fnb6884.js → cli-hvqbtna4.js} +7 -1259
  52. package/dist/{cli-pstq9888.js → cli-j0pfptdp.js} +220 -103
  53. package/dist/cli-jta2eyzc.js +619 -0
  54. package/dist/{cli-esnpehf5.js → cli-k382tshb.js} +12 -13
  55. package/dist/cli-k3dp5tpf.js +263 -0
  56. package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
  57. package/dist/cli-kceah1eh.js +92 -0
  58. package/dist/{cli-prrt9fa0.js → cli-ke896fcf.js} +10 -10
  59. package/dist/{cli-nv4zd0b9.js → cli-kt6zqg0e.js} +6 -6
  60. package/dist/{cli-g6t9texm.js → cli-m50t4309.js} +5 -18
  61. package/dist/cli-n2wq4j7m.js +6985 -0
  62. package/dist/{cli-c2pq2rjb.js → cli-n3hzg89b.js} +46 -15
  63. package/dist/{cli-tmhsxhb8.js → cli-n5vwg842.js} +23 -6
  64. package/dist/{cli-5rv1j9ga.js → cli-ne236afy.js} +53 -7
  65. package/dist/cli-p0sg24zp.js +16 -0
  66. package/dist/{cli-d161g69q.js → cli-p1x85d2t.js} +50 -2
  67. package/dist/{cli-7pz3b7x5.js → cli-przpmdgr.js} +25 -0
  68. package/dist/{cli-g4f5pj26.js → cli-q0ke1yww.js} +111 -25
  69. package/dist/{cli-e3pmyt39.js → cli-q50942rs.js} +1 -1
  70. package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
  71. package/dist/{cli-gj81e47t.js → cli-r2pnvj8g.js} +2 -2
  72. package/dist/{cli-r8smj8b8.js → cli-r62a35ea.js} +19 -3
  73. package/dist/{cli-cd0hv9nh.js → cli-ra0xzggj.js} +2 -2
  74. package/dist/cli-rhs9pz33.js +294 -0
  75. package/dist/{cli-nyhb1r6x.js → cli-s2sp957d.js} +52 -29
  76. package/dist/{cli-1x7da0de.js → cli-s4setq91.js} +8 -8
  77. package/dist/{cli-xczpdp9e.js → cli-se8w6wny.js} +6 -6
  78. package/dist/cli-skxvvpap.js +10140 -0
  79. package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
  80. package/dist/{cli-0p3enk35.js → cli-tqaazemc.js} +9 -1
  81. package/dist/{cli-cf69s3ew.js → cli-tr4sxp68.js} +3 -3
  82. package/dist/{cli-8hzfb6xz.js → cli-tsde1hdr.js} +15 -15
  83. package/dist/{cli-cceskcvt.js → cli-txqb9s38.js} +8 -8
  84. package/dist/{cli-aspcaef3.js → cli-v1yb0rqb.js} +6 -6
  85. package/dist/{cli-j1pmc07z.js → cli-vatyhshy.js} +268 -40
  86. package/dist/{cli-04emfe2q.js → cli-vdach5a9.js} +5 -5
  87. package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
  88. package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
  89. package/dist/{cli-hwwvy36w.js → cli-wayw93nt.js} +3 -3
  90. package/dist/cli-wmgrkscj.js +23254 -0
  91. package/dist/{cli-gp1rtyvk.js → cli-z5jjpaxw.js} +29 -6
  92. package/dist/{cli-451ks6aw.js → cli-zkpks3r3.js} +1 -1
  93. package/dist/cli.js +32 -48
  94. package/dist/{codex-adapter-m4tgdysy.js → codex-adapter-y81sssk0.js} +16 -15
  95. package/dist/{codex-login-841kv5fk.js → codex-login-f2rcfpp9.js} +3 -2
  96. package/dist/{codex-session-runner-ymwzm6ea.js → codex-session-runner-8vx4j6a9.js} +16 -15
  97. package/dist/{commands-n0hshcvs.js → commands-kcpvpcrr.js} +21 -10
  98. package/dist/{controller-hq5ggpcp.js → controller-ywrmt6yd.js} +5 -4
  99. package/dist/{controllers-connect-y07cqcvy.js → controllers-connect-kwpvj3rf.js} +45 -38
  100. package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-cehv1qns.js} +7 -6
  101. package/dist/{db-hkqvrdcb.js → db-k8ankj20.js} +13 -11
  102. package/dist/{db-4w7tmt1g.js → db-ww5d7jq3.js} +29 -9
  103. package/dist/{devin-adapter-xgtj680j.js → devin-adapter-x1022qb1.js} +3 -2
  104. package/dist/{dispatcher-5sd69y14.js → dispatcher-e8gq5m68.js} +41 -34
  105. package/dist/{docker-f503k9p0.js → docker-ff6y1190.js} +3 -2
  106. package/dist/{dsh-adapter-2h8m4cab.js → dsh-adapter-3epjm3af.js} +7 -6
  107. package/dist/{e2b-66xra4az.js → e2b-8ygwhg0f.js} +4 -3
  108. package/dist/{e2b-xwhyj8cw.js → e2b-swhnpw3n.js} +4 -3
  109. package/dist/{event-bus-vjtv82gm.js → event-bus-6axnngdj.js} +3 -2
  110. package/dist/external-channel-h3359cwn.js +52 -0
  111. package/dist/{google-generative-ai-7pavrbv7.js → google-generative-ai-g8db7x0f.js} +5 -3
  112. package/dist/{google-vertex-3f1jk41f.js → google-vertex-r2692q0r.js} +5 -3
  113. package/dist/{grok-adapter-8m9yqzbq.js → grok-adapter-0d4x7gkx.js} +19 -18
  114. package/dist/{handlers-s20xr10r.js → handlers-an1gzv21.js} +44 -37
  115. package/dist/{heartbeat-3k31q4g2.js → heartbeat-6dakeb61.js} +46 -39
  116. package/dist/{hook-gdn6a2fn.js → hook-6v6cv6d5.js} +12 -24
  117. package/dist/{hook-ygwerrdh.js → hook-sa5xye4y.js} +13 -12
  118. package/dist/{http-jdteeg81.js → http-r7f3eky0.js} +1598 -279
  119. package/dist/index-52j1aja4.js +3465 -0
  120. package/dist/{index-e0snym4t.js → index-7ep4gzdk.js} +41 -34
  121. package/dist/index-9gw58n4k.js +193 -0
  122. package/dist/index-9j87mcm8.js +56305 -0
  123. package/dist/index-bsmcresk.js +79424 -0
  124. package/dist/index-mh85qhec.js +475 -0
  125. package/dist/{index-vm3bm9t7.js → index-rmpw9a8q.js} +41 -34
  126. package/dist/{index-6ksewd5y.js → index-s2wxgzr0.js} +1015 -732
  127. package/dist/{index-tsszt7g9.js → index-v1v6n7hg.js} +46 -39
  128. package/dist/index-we27kd31.js +12810 -0
  129. package/dist/{index-ffqzqgwb.js → index-zk96aq1k.js} +11 -9
  130. package/dist/{keepalive-jekc896t.js → keepalive-be9vwy5h.js} +13 -11
  131. package/dist/{lead-4k9s9szx.js → lead-0861cwrf.js} +64 -57
  132. package/dist/{maintenance-shazch4n.js → maintenance-mzzgc8bn.js} +11 -9
  133. package/dist/node-c9we95xf.js +1 -1
  134. package/dist/{node-fkajaq96.js → node-mn1zs7an.js} +2 -1
  135. package/dist/{oauth-refresh-sweep-5gb36kn8.js → oauth-refresh-sweep-cpdnfwdj.js} +12 -10
  136. package/dist/{onboard-ydrbnvww.js → onboard-fh8qs4r3.js} +11 -3
  137. package/dist/{opencode-adapter-5zh0he20.js → opencode-adapter-nm42wwj8.js} +19 -14
  138. package/dist/{otel-impl-6pf5cv86.js → otel-impl-x6c1c9g4.js} +248 -869
  139. package/dist/{pi-mono-adapter-ef9wwx9m.js → pi-mono-adapter-9n2ya240.js} +245 -107
  140. package/dist/{pricing-refresh-s52nsa5q.js → pricing-refresh-qb0rv0ap.js} +13 -11
  141. package/dist/{rbac-roles-aq3msh4e.js → rbac-roles-1gzdwbh1.js} +12 -10
  142. package/dist/{rbac-roles-q5gb5e8v.js → rbac-roles-3mraey52.js} +13 -11
  143. package/dist/{render-v2-pd1rg54q.js → render-v2-agpa45zz.js} +19 -13
  144. package/dist/{resume-gw4a2c6v.js → resume-x0ydy9s9.js} +27 -21
  145. package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
  146. package/dist/{setup-jda1ksdh.js → setup-as9ga0d6.js} +2 -2
  147. package/dist/{virtual-modules-b3ga2m65.js → virtual-modules-9gkxqrap.js} +7 -6
  148. package/dist/{work-objects-tb7ycye8.js → work-objects-y5g1y7ev.js} +49 -37
  149. package/dist/{worker-njjccz5d.js → worker-860c3e38.js} +64 -57
  150. package/dist/{x-qfmygqqv.js → x-m477fr0h.js} +3 -2
  151. package/openapi.json +951 -356
  152. package/package.json +12 -13
  153. package/src/apps/catalog.generated.json +1309 -53
  154. package/src/apps/page-validator.ts +93 -31
  155. package/src/azure-devops/api.ts +94 -18
  156. package/src/azure-devops/auth.ts +32 -0
  157. package/src/azure-devops/boards-sync.ts +708 -0
  158. package/src/azure-devops/handlers.ts +52 -8
  159. package/src/azure-devops/html.ts +26 -0
  160. package/src/azure-devops/index.ts +15 -0
  161. package/src/azure-devops/templates.ts +86 -0
  162. package/src/azure-devops/types.ts +65 -1
  163. package/src/be/config-refs.ts +60 -0
  164. package/src/be/db/page-versions.ts +15 -0
  165. package/src/be/db/runtime.ts +35 -8
  166. package/src/be/db/skill-name-resolution.ts +36 -0
  167. package/src/be/db/tasks/read.ts +230 -0
  168. package/src/be/db/tasks/write.ts +7 -0
  169. package/src/be/db.ts +74 -13
  170. package/src/be/migrations/213_script_connections_sql.sql +79 -0
  171. package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
  172. package/src/be/migrations/216_task_resolved_effort.sql +5 -0
  173. package/src/be/migrations/217_chat_sdk_state.sql +104 -0
  174. package/src/be/model-catalog-store.ts +5 -1
  175. package/src/be/model-tier-resolution.ts +12 -1
  176. package/src/be/model-validation.ts +5 -2
  177. package/src/be/models-catalog.ts +26 -1
  178. package/src/be/modelsdev-cache.json +198 -63
  179. package/src/be/modelsdev-cache.ts +9 -1
  180. package/src/be/script-connections.ts +47 -8
  181. package/src/be/script-credential-broker.ts +39 -2
  182. package/src/be/scripts/run-saved.ts +1 -0
  183. package/src/be/scripts/typecheck.ts +10 -8
  184. package/src/be/seed/runner.ts +13 -1
  185. package/src/be/seed/state-db.ts +5 -0
  186. package/src/be/seed/types.ts +6 -0
  187. package/src/be/seed-pricing.ts +19 -2
  188. package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
  189. package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
  190. package/src/be/seed-skills/bundled-files.generated.json +10 -18
  191. package/src/be/seed-skills/index.ts +107 -3
  192. package/src/be/sql-connections.ts +118 -0
  193. package/src/be/swarm-config-guard.ts +53 -0
  194. package/src/cli.tsx +0 -16
  195. package/src/commands/onboard/non-interactive.ts +4 -2
  196. package/src/commands/profile-sync.ts +5 -3
  197. package/src/commands/provider-credentials.ts +52 -6
  198. package/src/commands/runner.ts +196 -56
  199. package/src/e2b/env.ts +5 -0
  200. package/src/extensions/contract-types.generated.ts +1 -1
  201. package/src/extensions/contract.ts +45 -0
  202. package/src/extensions/dispatcher.ts +7 -0
  203. package/src/extensions/post-bridge.ts +40 -0
  204. package/src/github/handlers.ts +11 -4
  205. package/src/heartbeat/templates.ts +8 -5
  206. package/src/hooks/hook.ts +0 -26
  207. package/src/http/all-routes.ts +0 -1
  208. package/src/http/config.ts +36 -17
  209. package/src/http/core.ts +4 -0
  210. package/src/http/index.ts +14 -2
  211. package/src/http/integrations.ts +88 -1
  212. package/src/http/mcp-oauth.ts +6 -13
  213. package/src/http/mcp.ts +15 -5
  214. package/src/http/page-proxy.ts +2 -4
  215. package/src/http/pages-public.ts +6 -5
  216. package/src/http/pages.ts +5 -14
  217. package/src/http/poll.ts +28 -68
  218. package/src/http/requested-by.ts +54 -0
  219. package/src/http/route-def.ts +7 -6
  220. package/src/http/script-connection-proxy.ts +51 -4
  221. package/src/http/script-connections.ts +5 -2
  222. package/src/http/scripts.ts +1 -0
  223. package/src/http/session-cost-recompute.ts +12 -2
  224. package/src/http/session-data.ts +4 -0
  225. package/src/http/stats.ts +1 -30
  226. package/src/http/tasks.ts +61 -5
  227. package/src/http/utils.ts +14 -0
  228. package/src/http/webhooks.ts +183 -2
  229. package/src/http/x.ts +1 -0
  230. package/src/integrations/chat-sdk/adapters.ts +129 -0
  231. package/src/integrations/chat-sdk/attachments.ts +232 -0
  232. package/src/integrations/chat-sdk/background.ts +36 -0
  233. package/src/integrations/chat-sdk/commands.ts +194 -0
  234. package/src/integrations/chat-sdk/config.ts +198 -0
  235. package/src/integrations/chat-sdk/discord-api.ts +63 -0
  236. package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
  237. package/src/integrations/chat-sdk/handlers.ts +28 -0
  238. package/src/integrations/chat-sdk/inbound.ts +426 -0
  239. package/src/integrations/chat-sdk/limits.ts +48 -0
  240. package/src/integrations/chat-sdk/logger.ts +81 -0
  241. package/src/integrations/chat-sdk/outbound.ts +123 -0
  242. package/src/integrations/chat-sdk/relay.ts +172 -0
  243. package/src/integrations/chat-sdk/router.ts +169 -0
  244. package/src/integrations/chat-sdk/runtime.ts +351 -0
  245. package/src/integrations/chat-sdk/schema.ts +245 -0
  246. package/src/integrations/chat-sdk/state.ts +243 -0
  247. package/src/integrations/chat-sdk/status.ts +244 -0
  248. package/src/integrations/chat-sdk/steering.ts +58 -0
  249. package/src/integrations/chat-sdk/teams-origin.ts +77 -0
  250. package/src/integrations/chat-sdk/telegram-api.ts +56 -0
  251. package/src/integrations/chat-sdk/templates.ts +16 -0
  252. package/src/integrations/chat-sdk/test-hooks.ts +37 -0
  253. package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
  254. package/src/integrations/chat-sdk/typing.ts +65 -0
  255. package/src/jira/adf.ts +3 -1
  256. package/src/kv-reserved-namespaces.ts +2 -0
  257. package/src/oauth/mcp-wrapper.ts +10 -6
  258. package/src/otel-impl.ts +2 -1
  259. package/src/pages/version.ts +4 -5
  260. package/src/prompts/base-prompt.ts +111 -45
  261. package/src/providers/acp-target-catalog.ts +6 -0
  262. package/src/providers/acp-targets.ts +56 -3
  263. package/src/providers/amp-adapter.ts +1 -1
  264. package/src/providers/claude-adapter.ts +27 -2
  265. package/src/providers/claude-flag-settings.ts +133 -0
  266. package/src/providers/claude-managed-adapter.ts +1 -1
  267. package/src/providers/claude-sdk-session.ts +7 -0
  268. package/src/providers/claude-session-events.ts +6 -1
  269. package/src/providers/dsh-adapter.ts +1 -1
  270. package/src/providers/opencode-adapter.ts +268 -37
  271. package/src/providers/opencode-billing.ts +86 -0
  272. package/src/providers/opencode-swarm-plugin.ts +51 -0
  273. package/src/providers/pi-mono-adapter.ts +398 -153
  274. package/src/providers/pricing-sources.md +37 -3
  275. package/src/providers/reasoning-effort.ts +27 -0
  276. package/src/providers/types.ts +11 -2
  277. package/src/rbac/legacy-policy.ts +8 -2
  278. package/src/rbac/permissions.ts +21 -0
  279. package/src/scheduler/scheduler.ts +4 -2
  280. package/src/scripts-runtime/api-client.ts +15 -1
  281. package/src/scripts-runtime/api-types.ts +9 -1
  282. package/src/scripts-runtime/ctx.ts +1 -1
  283. package/src/scripts-runtime/loader.ts +19 -7
  284. package/src/scripts-runtime/mcp-client.ts +30 -19
  285. package/src/scripts-runtime/sdk-allowlist.ts +8 -6
  286. package/src/scripts-runtime/swarm-sdk.ts +0 -11
  287. package/src/scripts-runtime/types/stdlib.d.ts +27 -15
  288. package/src/scripts-runtime/types/swarm-extension.d.ts +63 -1
  289. package/src/scripts-runtime/types/swarm-sdk.d.ts +27 -15
  290. package/src/server.ts +52 -18
  291. package/src/slack/actions.ts +29 -1
  292. package/src/slack/app.ts +14 -2
  293. package/src/slack/assistant.ts +36 -2
  294. package/src/slack/channel-join.ts +3 -16
  295. package/src/slack/commands.ts +9 -1
  296. package/src/slack/event-dedup.ts +1 -1
  297. package/src/slack/external-channel-egress.ts +113 -0
  298. package/src/slack/external-channel.ts +309 -0
  299. package/src/slack/handlers.ts +61 -0
  300. package/src/slack/render-v2.ts +40 -47
  301. package/src/slack/work-objects.ts +5 -0
  302. package/src/tasks/additive-buffer.ts +4 -2
  303. package/src/tasks/context-key.ts +94 -2
  304. package/src/tasks/model-pin.ts +67 -0
  305. package/src/tasks/worker-follow-up.ts +4 -31
  306. package/src/telemetry.ts +2 -1
  307. package/src/tests/acp-adapter.test.ts +42 -0
  308. package/src/tests/api-drain-worker-e2e.test.ts +1 -6
  309. package/src/tests/apps-catalog-feedback.test.ts +310 -0
  310. package/src/tests/apps-catalog-inputs.test.ts +70 -0
  311. package/src/tests/apps-catalog-table.test.ts +113 -0
  312. package/src/tests/azure-devops-boards-sync.test.ts +584 -0
  313. package/src/tests/azure-devops-html.test.ts +13 -0
  314. package/src/tests/azure-devops-webhook-malformed.test.ts +4 -0
  315. package/src/tests/base-prompt.test.ts +58 -54
  316. package/src/tests/chat-sdk-commands.test.ts +191 -0
  317. package/src/tests/chat-sdk-config.test.ts +334 -0
  318. package/src/tests/chat-sdk-discord-api.test.ts +68 -0
  319. package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
  320. package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
  321. package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
  322. package/src/tests/chat-sdk-harness.ts +146 -0
  323. package/src/tests/chat-sdk-inbound.test.ts +363 -0
  324. package/src/tests/chat-sdk-relay.test.ts +470 -0
  325. package/src/tests/chat-sdk-reload.test.ts +128 -0
  326. package/src/tests/chat-sdk-shutdown.test.ts +220 -0
  327. package/src/tests/chat-sdk-slack.test.ts +268 -0
  328. package/src/tests/chat-sdk-state.test.ts +163 -0
  329. package/src/tests/chat-sdk-status-route.test.ts +382 -0
  330. package/src/tests/chat-sdk-teams.test.ts +277 -0
  331. package/src/tests/chat-sdk-tools.test.ts +520 -0
  332. package/src/tests/chat-sdk-typing.test.ts +120 -0
  333. package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
  334. package/src/tests/claude-adapter-binary.test.ts +144 -0
  335. package/src/tests/claude-flag-settings.test.ts +114 -0
  336. package/src/tests/claude-managed-adapter.test.ts +1 -1
  337. package/src/tests/claude-sdk-lifecycle.test.ts +148 -1
  338. package/src/tests/claude-sdk-process.fixture.ts +7 -0
  339. package/src/tests/claude-thinking-tokens.test.ts +57 -0
  340. package/src/tests/claude-worker-parity.test.ts +2 -7
  341. package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
  342. package/src/tests/config-refs.test.ts +66 -0
  343. package/src/tests/context-key.test.ts +51 -0
  344. package/src/tests/cors-allowlist.test.ts +25 -0
  345. package/src/tests/create-page-tool.test.ts +18 -0
  346. package/src/tests/credential-check.test.ts +139 -0
  347. package/src/tests/credentials.test.ts +21 -0
  348. package/src/tests/db-runtime.test.ts +61 -0
  349. package/src/tests/db-task-read-contract.test.ts +20 -0
  350. package/src/tests/db-task-write-contract.test.ts +10 -0
  351. package/src/tests/deferred-task-wake.test.ts +52 -4
  352. package/src/tests/docs-index-footprint.test.js +3 -3
  353. package/src/tests/dsh-adapter.test.ts +1 -1
  354. package/src/tests/enabled-capabilities.test.ts +20 -0
  355. package/src/tests/entrypoint-api-readiness.test.ts +14 -8
  356. package/src/tests/entrypoint-config-env-export.test.ts +5 -2
  357. package/src/tests/entrypoint-export-to-env.test.ts +78 -0
  358. package/src/tests/explicit-model-validation.test.ts +105 -1
  359. package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
  360. package/src/tests/extensions-post-bridge.test.ts +51 -0
  361. package/src/tests/fetch-resolved-env.test.ts +128 -0
  362. package/src/tests/fixtures/azure-boards/workitem.commented.json +89 -0
  363. package/src/tests/fixtures/azure-boards/workitem.created.json +81 -0
  364. package/src/tests/fixtures/azure-boards/workitem.deleted.json +70 -0
  365. package/src/tests/fixtures/azure-boards/workitem.restored.json +82 -0
  366. package/src/tests/fixtures/azure-boards/workitem.updated.json +130 -0
  367. package/src/tests/fixtures/catalog-feedback-definition.json.txt +860 -0
  368. package/src/tests/fixtures/catalog-inputs-definition.json.txt +910 -0
  369. package/src/tests/fixtures/catalog-table-definition.json.txt +468 -0
  370. package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
  371. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
  372. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
  373. package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
  374. package/src/tests/fixtures/runner-identity-refresh.ts +3 -0
  375. package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
  376. package/src/tests/github-handlers.test.ts +35 -0
  377. package/src/tests/harness-provider-resolution.test.ts +12 -0
  378. package/src/tests/heartbeat-checklist.test.ts +3 -2
  379. package/src/tests/hook-runtime-close.test.ts +0 -2
  380. package/src/tests/http-api-integration.test.ts +0 -25
  381. package/src/tests/migration-046-budgets.test.ts +17 -16
  382. package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
  383. package/src/tests/model-tier-resolution.test.ts +93 -0
  384. package/src/tests/models-catalog.test.ts +42 -1
  385. package/src/tests/node-env-runtime.test.ts +98 -0
  386. package/src/tests/openai-compatible-providers.test.ts +134 -0
  387. package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
  388. package/src/tests/opencode-adapter.test.ts +348 -3
  389. package/src/tests/opencode-billing.test.ts +28 -0
  390. package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
  391. package/src/tests/opencode-shell-env.test.ts +145 -0
  392. package/src/tests/openrouter-base-url.test.ts +101 -151
  393. package/src/tests/page-proxy.test.ts +1 -1
  394. package/src/tests/pages-browser-sdk.test.ts +76 -0
  395. package/src/tests/pages-feedback.test.ts +1 -1
  396. package/src/tests/paused-tasks-requested-by.test.ts +102 -0
  397. package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
  398. package/src/tests/pi-mono-adapter.test.ts +385 -5
  399. package/src/tests/pi-shell-env.test.ts +170 -0
  400. package/src/tests/prompt-template-remaining.test.ts +35 -0
  401. package/src/tests/rbac-engine.test.ts +11 -3
  402. package/src/tests/runner-exit-after-tasks.test.ts +0 -4
  403. package/src/tests/runner-identity-refresh.test.ts +3 -0
  404. package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
  405. package/src/tests/script-connections-sql.test.ts +675 -0
  406. package/src/tests/script-connections.test.ts +7 -1
  407. package/src/tests/scripts-http.test.ts +201 -1
  408. package/src/tests/scripts-only-gating.test.ts +2 -3
  409. package/src/tests/scripts-runtime.test.ts +58 -40
  410. package/src/tests/secret-scrubber.test.ts +86 -0
  411. package/src/tests/seed-skills-bundled-files.test.ts +45 -53
  412. package/src/tests/seed-skills-retire.test.ts +182 -0
  413. package/src/tests/send-task-requester-gate.test.ts +58 -0
  414. package/src/tests/session-cost-recompute-unit.test.ts +94 -0
  415. package/src/tests/skill-get-name-resolution.test.ts +137 -0
  416. package/src/tests/slack-channel-join.test.ts +4 -1
  417. package/src/tests/slack-external-channel-config.test.ts +65 -0
  418. package/src/tests/slack-external-channel-egress.test.ts +237 -0
  419. package/src/tests/slack-external-channel-guard.test.ts +280 -0
  420. package/src/tests/slack-external-channel-tools.test.ts +173 -0
  421. package/src/tests/slack-external-channel.test.ts +370 -0
  422. package/src/tests/slack-render-v2.test.ts +86 -10
  423. package/src/tests/sonnet-5-5-registry.test.ts +9 -1
  424. package/src/tests/spec-base-url.test.ts +16 -1
  425. package/src/tests/swarm-config-export-to-env.test.ts +267 -0
  426. package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
  427. package/src/tests/swarm-diff.test.ts +1 -1
  428. package/src/tests/task-model-effort-rerun.test.ts +164 -0
  429. package/src/tests/task-session-prompts.test.ts +132 -0
  430. package/src/tests/task-tool-manifest.test.ts +14 -0
  431. package/src/tests/task-tools-ctx.test.ts +2 -0
  432. package/src/tests/tool-annotations.test.ts +6 -6
  433. package/src/tests/ui-logs-parser.test.ts +43 -0
  434. package/src/tests/used-by-route.test.ts +6 -0
  435. package/src/tests/vendored-openapi.test.ts +16 -1
  436. package/src/tests/vercel-ai-gateway.test.ts +149 -0
  437. package/src/tests/workflow-swarm-script.test.ts +38 -0
  438. package/src/tests/workflow-wait-filter.test.ts +5 -3
  439. package/src/tools/chat-access.ts +41 -0
  440. package/src/tools/chat-open-dm.ts +59 -0
  441. package/src/tools/chat-post.ts +74 -0
  442. package/src/tools/chat-read-thread.ts +100 -0
  443. package/src/tools/chat-reply.ts +75 -0
  444. package/src/tools/create-page.ts +3 -13
  445. package/src/tools/defer-task.ts +17 -0
  446. package/src/tools/model-catalog/index.ts +2 -1
  447. package/src/tools/register-chat-channel.ts +139 -0
  448. package/src/tools/send-task.ts +24 -0
  449. package/src/tools/skills/skill-get.ts +17 -9
  450. package/src/tools/slack-post.ts +6 -0
  451. package/src/tools/slack-read.ts +8 -0
  452. package/src/tools/slack-reply.ts +6 -0
  453. package/src/tools/slack-start-thread.ts +6 -0
  454. package/src/tools/slack-update.ts +6 -0
  455. package/src/tools/slack-upload-file.ts +6 -0
  456. package/src/tools/swarm-config/get-config.ts +2 -1
  457. package/src/tools/swarm-config/list-config.ts +2 -1
  458. package/src/tools/swarm-config/set-config.ts +16 -3
  459. package/src/tools/tool-config.ts +8 -6
  460. package/src/types.ts +12 -2
  461. package/src/utils/config-env-export.ts +74 -0
  462. package/src/utils/credentials.test.ts +92 -0
  463. package/src/utils/credentials.ts +52 -4
  464. package/src/utils/harness-provider.ts +15 -6
  465. package/src/utils/node-env.ts +24 -0
  466. package/src/utils/runtime-model-catalog.ts +11 -1
  467. package/src/utils/secret-scrubber.ts +71 -2
  468. package/src/utils/task-tool-manifest.ts +19 -2
  469. package/src/workflows/executors/swarm-script.ts +1 -0
  470. package/templates/skills/agent-browser/SKILL.md +1 -1
  471. package/templates/skills/agent-browser/content.md +1 -1
  472. package/templates/skills/apps/SKILL.md +749 -0
  473. package/templates/skills/apps/content.md +60 -22
  474. package/templates/skills/chat-sdk/config.json +14 -0
  475. package/templates/skills/chat-sdk/content.md +84 -0
  476. package/templates/skills/composio-gmail/content.md +7 -0
  477. package/templates/skills/composio-google-docs/content.md +1 -1
  478. package/templates/skills/email-domain-health/config.json +14 -0
  479. package/templates/skills/email-domain-health/content.md +131 -0
  480. package/templates/skills/kv-storage/content.md +2 -2
  481. package/templates/skills/pages/content.md +8 -10
  482. package/templates/skills/qa-loom/config.json +14 -0
  483. package/templates/skills/qa-loom/content.md +187 -0
  484. package/templates/skills/qa-loom/files/build-loom.mjs +221 -0
  485. package/templates/skills/qa-loom/files/run-qa.sh +57 -0
  486. package/templates/skills/slack-interaction/content.md +4 -0
  487. package/templates/skills/swarm-extensions/content.md +2 -0
  488. package/templates/skills/swarm-scripts/SKILL.md +4 -2
  489. package/templates/skills/swarm-scripts/config.json +1 -1
  490. package/templates/skills/swarm-scripts/content.md +4 -2
  491. package/templates/skills/workflow-iterate/content.md +38 -0
  492. package/dist/artifact-eczsknc3.js +0 -3843
  493. package/dist/cli-9xsmdpdt.js +0 -56377
  494. package/dist/cli-bd957dgb.js +0 -153
  495. package/dist/cli-q51yprfq.js +0 -1104
  496. package/dist/cli-t1ze64h3.js +0 -811
  497. package/dist/index-9ch1n761.js +0 -1102
  498. package/src/artifact-sdk/index.ts +0 -2
  499. package/src/artifact-sdk/localtunnel.d.ts +0 -20
  500. package/src/artifact-sdk/port.ts +0 -12
  501. package/src/artifact-sdk/server.ts +0 -183
  502. package/src/artifact-sdk/tunnel.ts +0 -19
  503. package/src/commands/artifact.ts +0 -249
  504. package/src/http/ecosystem.ts +0 -77
  505. package/src/tests/artifact-commands.test.ts +0 -92
  506. package/src/tests/artifact-sdk.test.ts +0 -793
  507. package/src/tests/register-service-security.test.ts +0 -194
  508. package/src/tools/list-services.ts +0 -107
  509. package/src/tools/register-service.ts +0 -177
  510. package/src/tools/unregister-service.ts +0 -73
  511. package/src/tools/update-service-status.ts +0 -96
  512. package/templates/skills/artifacts/config.json +0 -14
  513. package/templates/skills/artifacts/content.md +0 -344
  514. package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
  515. package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
  516. package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
  517. package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
  518. package/dist/{azure-openai-responses-ap1gwxgr.js → azure-openai-responses-ygfreq4t.js} +5 -5
  519. package/dist/{cli-5rqrj7q0.js → cli-pw7ebjdt.js} +0 -0
  520. package/dist/{openai-codex-responses-33qhkkdy.js → openai-codex-responses-3bk0grnr.js} +4 -4
  521. package/dist/{openai-completions-s88xm3ns.js → openai-completions-5d4jpakc.js} +9 -9
  522. package/dist/{openai-responses-7xd2f2e2.js → openai-responses-krb51f59.js} +5 -5
  523. package/dist/{pi-messages-xszk613n.js → pi-messages-x9gzynm1.js} +3 -3
  524. /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
  525. /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-gj81e47t.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-8hzfb6xz.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-prrt9fa0.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,
@@ -183,6 +187,11 @@ import {
183
187
  handlePullRequestCreated,
184
188
  handlePullRequestReview,
185
189
  handleWebhookTrigger,
190
+ handleWorkItemCommented,
191
+ handleWorkItemCreated,
192
+ handleWorkItemDeleted,
193
+ handleWorkItemRestored,
194
+ handleWorkItemUpdated,
186
195
  handleWorkflowRun,
187
196
  harnessModelErrorFor,
188
197
  hasCapability,
@@ -202,6 +211,9 @@ import {
202
211
  isAgentMailEnabled,
203
212
  isApiDraining,
204
213
  isAzureDevOpsEnabled,
214
+ isChatAdapterConfigured,
215
+ isChatSdkEnabled,
216
+ isChatSdkStopping,
205
217
  isGitHubEnabled,
206
218
  isGitLabEnabled,
207
219
  isInboxAllowed,
@@ -213,6 +225,7 @@ import {
213
225
  isLinearEnabled,
214
226
  isOriginAllowedForCredentials,
215
227
  isSenderAllowed,
228
+ isTrustedTeamsServiceUrl,
216
229
  issuePageSessionCookie,
217
230
  json,
218
231
  jsonError,
@@ -236,7 +249,6 @@ import {
236
249
  parseCookieHeader,
237
250
  parseModelTierOverridesHeader,
238
251
  parseQueryParams,
239
- parseSkillContent,
240
252
  patchWorkflowDefinition,
241
253
  poolTaskRunsOnHarness,
242
254
  posteriorMean,
@@ -262,6 +274,7 @@ import {
262
274
  reservedRoomKeyError,
263
275
  resetAgentMaxTasksMirror,
264
276
  resetRoom,
277
+ resolveAdapterApiUrl,
265
278
  resolveHttpAuditUserId,
266
279
  resolveHttpFavoriteOwner,
267
280
  resolveHttpRequestAuth,
@@ -296,17 +309,21 @@ import {
296
309
  snapshotPage,
297
310
  startAuditGc,
298
311
  startAuditWriter,
312
+ startChatSdk,
299
313
  steerTaskHandler,
300
314
  steerTaskOutputSchema,
301
315
  steerTaskUserInputSchema,
302
316
  stopAuditGc,
303
317
  stopAuditWriter,
318
+ stopChatSdk,
304
319
  stopExtensionRuntime,
305
320
  stripSiblingBlock,
306
321
  sweepRooms,
307
322
  syncTelemetryEnabled,
323
+ taskModelPin,
308
324
  toolErr,
309
325
  touchRuntimeInstance,
326
+ trackBackground,
310
327
  triggerSchemaErrorResponse,
311
328
  uninstallExtension,
312
329
  updateExtensionMeta,
@@ -327,13 +344,13 @@ import {
327
344
  wireHttpSpanLifecycle,
328
345
  workflowModelErrors,
329
346
  writeUnhandledError
330
- } from "./cli-ztrv9y21.js";
331
- import"./cli-451ks6aw.js";
347
+ } from "./cli-bzszjf2p.js";
348
+ import"./cli-zkpks3r3.js";
332
349
  import {
333
350
  AMP_ESTIMATE_MODELS,
334
351
  ampBillsCacheWrites,
335
352
  resolveAmpModel
336
- } from "./cli-2bw3w47j.js";
353
+ } from "./cli-hnhtk6cj.js";
337
354
  import {
338
355
  RATING_MODEL_MAX_LENGTH,
339
356
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -342,16 +359,12 @@ import {
342
359
  import {
343
360
  isMultiRuntimeEnabled
344
361
  } from "./cli-re8z5p8p.js";
345
- import"./cli-6jb2rf77.js";
346
362
  import {
347
363
  deleteModelCatalogOverlay,
348
364
  loadModelsCatalog,
349
365
  requestModelCatalogRefresh,
350
366
  upsertModelCatalogOverlay
351
- } from "./cli-gp1rtyvk.js";
352
- import {
353
- normalizeModelKey
354
- } from "./cli-r8smj8b8.js";
367
+ } from "./cli-z5jjpaxw.js";
355
368
  import {
356
369
  ConnectionAuthInputSchema,
357
370
  MAX_SCRIPT_WALL_CLOCK_MS,
@@ -359,6 +372,7 @@ import {
359
372
  SCRIPT_SDK_TYPES,
360
373
  SCRIPT_STDLIB_MODULE_TYPES,
361
374
  ScriptConnectionConflictError,
375
+ SqlDsnInputSchema,
362
376
  applyMcpOAuthRefresh,
363
377
  assertUrlSafe,
364
378
  authMethodForStoredClient,
@@ -402,8 +416,10 @@ import {
402
416
  listScriptConnectionsAsync,
403
417
  listVendoredOpenapiEntries,
404
418
  markMcpOAuthTokenStatus,
419
+ mcpOAuthSsrfOptions,
405
420
  normalizeTokenEndpointAuthMethod,
406
421
  oauthAppToProviderConfig,
422
+ parseSkillContent,
407
423
  publicEndpointSsrfOptions,
408
424
  readStreamCapped,
409
425
  refreshMcpToken,
@@ -412,7 +428,9 @@ import {
412
428
  require_dist,
413
429
  require_typescript,
414
430
  resolveAdvertisedTokenEndpointAuthMethod,
431
+ resolveSqlDsn,
415
432
  revokeMcpToken,
433
+ runReadOnlyQuery,
416
434
  runScript,
417
435
  sandboxSpawnEnv,
418
436
  scriptSdkTypesWithGeneratedApis,
@@ -425,7 +443,7 @@ import {
425
443
  upsertCredentialBinding,
426
444
  upsertMcpOAuthToken,
427
445
  upsertScriptConnection
428
- } from "./cli-j6kpj9az.js";
446
+ } from "./cli-ee9gtz70.js";
429
447
  import"./cli-epan13p1.js";
430
448
  import {
431
449
  detachedProcessGroup,
@@ -440,7 +458,12 @@ import {
440
458
  forceRefreshAuthorizationOrThrow,
441
459
  forceRefreshTokenOrThrow,
442
460
  oauthAppRowToProviderConfig
443
- } from "./cli-388egyf6.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";
444
467
  import {
445
468
  AgentFsProvider,
446
469
  FilesError,
@@ -459,14 +482,14 @@ import {
459
482
  startWorkflowExecution,
460
483
  validateJsonSchema,
461
484
  workflowSaveWarnings
462
- } from "./cli-kb4ehzx5.js";
485
+ } from "./cli-1e4b6bzh.js";
463
486
  import {
464
487
  createApprovalFollowUpTask,
465
488
  definitionNodeIds,
466
489
  generateEdges,
467
490
  validateDefinition
468
- } from "./cli-aspcaef3.js";
469
- import"./cli-xczpdp9e.js";
491
+ } from "./cli-v1yb0rqb.js";
492
+ import"./cli-se8w6wny.js";
470
493
  import {
471
494
  CLIENT_ID,
472
495
  MAX_CODEX_OAUTH_SLOT,
@@ -477,13 +500,14 @@ import {
477
500
  getAccountId,
478
501
  getValidCodexOAuth,
479
502
  loadAllCodexOAuthSlots
480
- } from "./cli-7jykv7ef.js";
481
- import"./cli-cceskcvt.js";
482
- import"./cli-h6vtvt5c.js";
503
+ } from "./cli-e6mpjhed.js";
483
504
  import"./cli-2x0e561b.js";
505
+ import"./cli-txqb9s38.js";
506
+ import"./cli-h6vtvt5c.js";
484
507
  import"./cli-fad8m16k.js";
485
508
  import"./cli-bsakbbkm.js";
486
509
  import"./cli-zxg80zs9.js";
510
+ import"./cli-51tf7ac3.js";
487
511
  import"./cli-ydt3zkwv.js";
488
512
  import {
489
513
  TaskCitationSchema,
@@ -499,18 +523,22 @@ import {
499
523
  recordDbRetentionStatement,
500
524
  recordDbRetentionSweep,
501
525
  recordSessionCost,
502
- require_content_type,
503
526
  startSlackApp,
504
527
  startSpan,
505
528
  stopSlackApp,
506
529
  withRemoteContext,
507
530
  withSpan,
508
531
  withSpanContext
509
- } from "./cli-9xsmdpdt.js";
510
- 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";
511
537
  import"./cli-3er6gcsn.js";
512
- import"./cli-yatxqynm.js";
513
- import"./cli-51tf7ac3.js";
538
+ import"./cli-hjwmhcg1.js";
539
+ import"./cli-rhs9pz33.js";
540
+ import"./cli-9ha6hs2d.js";
541
+ import"./cli-k3dp5tpf.js";
514
542
  import {
515
543
  InvalidRuntimeTokenError,
516
544
  RuntimePoolError,
@@ -549,11 +577,11 @@ import {
549
577
  unlinkIdentity,
550
578
  updateRuntimeController,
551
579
  updateRuntimePool
552
- } from "./cli-e0a9sk00.js";
553
- import"./cli-cd0hv9nh.js";
580
+ } from "./cli-eejsgvm4.js";
581
+ import"./cli-ra0xzggj.js";
554
582
  import {
555
583
  bedrockProviderModule
556
- } from "./cli-4fnb6884.js";
584
+ } from "./cli-hvqbtna4.js";
557
585
  import"./cli-phre6gz0.js";
558
586
  import"./cli-eh1ytktb.js";
559
587
  import"./cli-txgcknmy.js";
@@ -564,11 +592,11 @@ import"./cli-7kyk9jr3.js";
564
592
  import {
565
593
  setBedrockProviderModule
566
594
  } from "./cli-61625k3x.js";
567
- import"./cli-btbzvq95.js";
568
595
  import"./cli-1m2e086m.js";
596
+ import"./cli-btbzvq95.js";
569
597
  import"./cli-p7z6q2m6.js";
570
598
  import"./cli-wnb9b2g3.js";
571
- import"./cli-bd957dgb.js";
599
+ import"./cli-f527ce74.js";
572
600
  import {
573
601
  import_websocket,
574
602
  import_websocket_server
@@ -577,7 +605,7 @@ import"./cli-pzxba7gw.js";
577
605
  import {
578
606
  getUserGrant,
579
607
  init_rbac_roles
580
- } from "./cli-qsztpfry.js";
608
+ } from "./cli-74ahz61x.js";
581
609
  import {
582
610
  LEGACY_RULES,
583
611
  can,
@@ -586,10 +614,12 @@ import {
586
614
  init_rbac,
587
615
  isRbacEnabled,
588
616
  setAuditSink
589
- } from "./cli-7pz3b7x5.js";
617
+ } from "./cli-przpmdgr.js";
590
618
  import {
591
619
  API_DRAINING_HEADER,
592
620
  CANDIDATE_SET_MULTIPLIER,
621
+ CHAT_SDK_ADAPTER_NAMES,
622
+ CHAT_TASK_ONLY_TOOLS,
593
623
  CODEX_AUTH_WATCH_NAMESPACE,
594
624
  CredentialBindingSchema,
595
625
  DB_RETENTION_TUNING_BOUNDS,
@@ -616,6 +646,7 @@ import {
616
646
  cancelTask,
617
647
  catalog_default,
618
648
  channelTopic,
649
+ chatThreadOfContextKey,
619
650
  checkoutPromptTemplate,
620
651
  claimKv,
621
652
  claimMentions,
@@ -705,7 +736,6 @@ import {
705
736
  getAllChannelActivityCursors,
706
737
  getAllLogs,
707
738
  getAllPricingRows,
708
- getAllServices,
709
739
  getAllSessionCosts,
710
740
  getAllTasks,
711
741
  getAllUsers,
@@ -777,7 +807,6 @@ import {
777
807
  getScriptRunByIdempotencyKey,
778
808
  getScriptRunExecutionArgs,
779
809
  getScriptRunJournalStep,
780
- getServicesByAgentId,
781
810
  getSessionCostSummary,
782
811
  getSessionCostsByAgentId,
783
812
  getSessionCostsByTaskId,
@@ -840,6 +869,7 @@ import {
840
869
  init_reranker,
841
870
  init_runtime,
842
871
  init_runtime_pools_flag,
872
+ init_schema,
843
873
  init_secret_registry,
844
874
  init_steering,
845
875
  init_swarm_config_guard,
@@ -856,6 +886,9 @@ import {
856
886
  installMcpServer,
857
887
  installSkill,
858
888
  internalConfigKeyError,
889
+ isAdapterEntryEnabled,
890
+ isApiOnlyConfigKey,
891
+ isChatSdkTask,
859
892
  isExtensionAgent,
860
893
  isFilledOrgLogoUrl,
861
894
  isInternalConfigKey,
@@ -988,9 +1021,10 @@ import {
988
1021
  upsertSkillFiles,
989
1022
  upsertSwarmConfig,
990
1023
  validateConfigValue,
1024
+ validateExportToEnv,
991
1025
  withFavoriteFlags
992
- } from "./cli-tgpfnm6r.js";
993
- import"./cli-ywm1azg9.js";
1026
+ } from "./cli-ef1hg1wv.js";
1027
+ import"./cli-hnmhtzvh.js";
994
1028
  import {
995
1029
  ActiveSessionSchema,
996
1030
  AgentAcpStatusSchema,
@@ -1086,7 +1120,6 @@ import {
1086
1120
  ScriptRunStatusSchema,
1087
1121
  ScriptScopeSchema,
1088
1122
  ScriptVersionRecordSchema,
1089
- ServiceSchema,
1090
1123
  SessionCostModelBreakdownSchema,
1091
1124
  SessionCostSchema,
1092
1125
  SessionLogSchema,
@@ -1126,22 +1159,22 @@ import {
1126
1159
  isSafeBundlePath,
1127
1160
  isTerminalTaskStatus,
1128
1161
  splitLegacyModelAlias
1129
- } from "./cli-hsem16hb.js";
1162
+ } from "./cli-cgtksawx.js";
1130
1163
  import {
1131
1164
  IDENTITY_FIELD_BUDGETS,
1132
1165
  IdentityFieldBudgetError,
1133
1166
  init_identity_field_budget
1134
- } from "./cli-nyhb1r6x.js";
1135
- import {
1136
- init_steering_enabled,
1137
- isSteeringEnabled
1138
- } from "./cli-7mm2r1kp.js";
1167
+ } from "./cli-s2sp957d.js";
1139
1168
  import {
1140
1169
  getSlackConfiguration,
1141
1170
  init_config
1142
1171
  } from "./cli-dmtrxqhg.js";
1172
+ import {
1173
+ init_steering_enabled,
1174
+ isSteeringEnabled
1175
+ } from "./cli-7mm2r1kp.js";
1176
+ import"./cli-5hkm7whv.js";
1143
1177
  import"./cli-mvzyxwg3.js";
1144
- import"./cli-tadfgd0t.js";
1145
1178
  import {
1146
1179
  getAllTemplateDefinitions,
1147
1180
  getTemplateDefinition,
@@ -1168,10 +1201,7 @@ import {
1168
1201
  getOpenRouterAttributionHeaders,
1169
1202
  init_openrouter_base_url
1170
1203
  } from "./cli-a35hzdve.js";
1171
- import {
1172
- init_src,
1173
- isAlias
1174
- } from "./cli-014vns2y.js";
1204
+ import"./cli-stfs0k5s.js";
1175
1205
  import {
1176
1206
  exports_zod,
1177
1207
  init_zod
@@ -1185,20 +1215,24 @@ import {
1185
1215
  string,
1186
1216
  unknown
1187
1217
  } from "./cli-w5e1d1vv.js";
1218
+ import {
1219
+ getNodeEnv,
1220
+ init_node_env
1221
+ } from "./cli-p0sg24zp.js";
1188
1222
  import {
1189
1223
  init_package,
1190
1224
  package_default
1191
- } from "./cli-esnpehf5.js";
1225
+ } from "./cli-k382tshb.js";
1192
1226
  import {
1193
1227
  init_event_bus,
1194
1228
  workflowEventBus
1195
- } from "./cli-81r1wjyv.js";
1229
+ } from "./cli-9nfx44eh.js";
1196
1230
  import {
1197
1231
  init_bus,
1198
1232
  realtimeBus
1199
1233
  } from "./cli-zf8jjwex.js";
1200
1234
  import"./cli-h8w3fg83.js";
1201
- import"./cli-db3m6zdt.js";
1235
+ import"./cli-d2qr7aj4.js";
1202
1236
  import {
1203
1237
  MAX_PROFILE_FILE_LENGTH,
1204
1238
  agentFsFileRoute,
@@ -1214,7 +1248,7 @@ import {
1214
1248
  parseEnvFlag
1215
1249
  } from "./cli-ej6gbxfb.js";
1216
1250
  import"./cli-1srmzpr3.js";
1217
- import"./cli-0p3enk35.js";
1251
+ import"./cli-tqaazemc.js";
1218
1252
  import {
1219
1253
  getApiKey,
1220
1254
  init_api_key
@@ -1225,7 +1259,11 @@ import {
1225
1259
  registerVolatileSecret,
1226
1260
  scrubObject,
1227
1261
  scrubSecrets
1228
- } from "./cli-d161g69q.js";
1262
+ } from "./cli-p1x85d2t.js";
1263
+ import {
1264
+ init_src,
1265
+ isAlias
1266
+ } from "./cli-e3g5mbkz.js";
1229
1267
  import {
1230
1268
  __require,
1231
1269
  __toESM
@@ -7508,9 +7546,8 @@ init_request_auth_context();
7508
7546
  init_secret_scrubber();
7509
7547
  var MAX_ENV_PRESENCE_KEYS = 200;
7510
7548
  var SECRETS_FORCE_MASK_NOTE = " (secret values masked: this token cannot read secrets in this scope)";
7511
- var API_ONLY_CONFIG_KEYS = new Set(["API_AGENT_FS_API_KEY", "SLACK_SIGNING_SECRET"]);
7512
7549
  function stripApiOnlyKeys(configs) {
7513
- 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));
7514
7551
  }
7515
7552
  function singleHeader(req, name) {
7516
7553
  const raw = req.headers[name];
@@ -7552,6 +7589,9 @@ async function resolveSecretsRead(req, includeSecrets, resolvedScope) {
7552
7589
  };
7553
7590
  }
7554
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) {
7555
7595
  const auth = getRequestAuth(req);
7556
7596
  if (auth?.kind === "operator" || auth?.kind === "user")
7557
7597
  return true;
@@ -7568,7 +7608,7 @@ async function ensureConfigAdmin(req, res, verb) {
7568
7608
  source: "http"
7569
7609
  });
7570
7610
  if (!decision.allow) {
7571
- 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);
7572
7612
  return false;
7573
7613
  }
7574
7614
  return true;
@@ -7686,7 +7726,8 @@ var upsertConfig = route({
7686
7726
  value: exports_external.unknown(),
7687
7727
  isSecret: exports_external.boolean().optional(),
7688
7728
  envPath: exports_external.string().nullish(),
7689
- 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.")
7690
7731
  }),
7691
7732
  responses: {
7692
7733
  200: { description: "Config entry upserted", schema: SwarmConfigSchema },
@@ -7825,7 +7866,7 @@ async function handleConfig(req, res, pathSegments, queryParams) {
7825
7866
  return true;
7826
7867
  if (!await ensureConfigAdmin(req, res, "config.write.any"))
7827
7868
  return true;
7828
- const { scope, scopeId, key, value, isSecret, envPath, description } = parsed.body;
7869
+ const { scope, scopeId, key, value, isSecret, envPath, description, exportToEnv } = parsed.body;
7829
7870
  if (scope === "global" && scopeId) {
7830
7871
  jsonError(res, "Global scope must not have scopeId", 400);
7831
7872
  return true;
@@ -7842,7 +7883,7 @@ async function handleConfig(req, res, pathSegments, queryParams) {
7842
7883
  jsonError(res, internalConfigKeyError(key).message, 400);
7843
7884
  return true;
7844
7885
  }
7845
- const validationError = validateConfigValue(key, value);
7886
+ const validationError = validateConfigValue(key, value) ?? validateExportToEnv(key, exportToEnv);
7846
7887
  if (validationError) {
7847
7888
  jsonError(res, validationError, 400);
7848
7889
  return true;
@@ -7856,7 +7897,8 @@ async function handleConfig(req, res, pathSegments, queryParams) {
7856
7897
  value: String(value),
7857
7898
  isSecret: isSecret || false,
7858
7899
  envPath: envPath || null,
7859
- description: description || null
7900
+ description: description || null,
7901
+ exportToEnv
7860
7902
  });
7861
7903
  if (scope === "global" && key === "SWARM_ORG_WEBSITE") {
7862
7904
  await fillOrgLogoFromWebsite(String(value));
@@ -8414,7 +8456,7 @@ async function sendReviewBatch(input, deps = {}) {
8414
8456
  const target = targets[index];
8415
8457
  const isRepair = index >= wonIds.length;
8416
8458
  if (reply.status === "rejected") {
8417
- 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)}`));
8418
8460
  if (isRepair)
8419
8461
  skipped.push(alreadySent(target.id, target.taskId));
8420
8462
  } else if (isRepair) {
@@ -8445,7 +8487,7 @@ async function readComment(agentFs, drive, versionOf, id) {
8445
8487
  } catch (error) {
8446
8488
  if (error instanceof FilesError && error.code === "NotFound")
8447
8489
  return { id, thread: null };
8448
- 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)}`));
8449
8491
  }
8450
8492
  const { comment } = thread;
8451
8493
  const version = comment.fileVersion ?? (comment.parentId ? undefined : await versionOf(comment));
@@ -8505,7 +8547,7 @@ async function settleClaims(ids, claim, next) {
8505
8547
  settled.forEach((result, index) => {
8506
8548
  if (result.status === "fulfilled" && result.value)
8507
8549
  return;
8508
- 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";
8509
8551
  console.warn(scrubSecrets(`[comb] could not ${next ? "record" : "release"} the claim on comment=${ids[index]}: ${why}`));
8510
8552
  });
8511
8553
  }
@@ -8607,7 +8649,7 @@ async function requesterLabel(userId) {
8607
8649
  return "an operator (swarm API key)";
8608
8650
  return user.email ? `${user.name} <${user.email}>` : user.name;
8609
8651
  }
8610
- function errorMessage(error) {
8652
+ function errorMessage2(error) {
8611
8653
  return error instanceof Error ? error.message : String(error);
8612
8654
  }
8613
8655
 
@@ -8814,64 +8856,6 @@ async function handleContext(req, res, pathSegments, queryParams, myAgentId) {
8814
8856
  return false;
8815
8857
  }
8816
8858
 
8817
- // src/http/ecosystem.ts
8818
- init_zod();
8819
- init_db3();
8820
- var EcosystemAppSchema = exports_external.object({
8821
- name: exports_external.string(),
8822
- script: exports_external.string(),
8823
- cwd: exports_external.string().optional(),
8824
- interpreter: exports_external.string().optional(),
8825
- args: exports_external.array(exports_external.string()).optional(),
8826
- env: exports_external.record(exports_external.string(), exports_external.string()).optional()
8827
- });
8828
- var getEcosystem = route({
8829
- method: "get",
8830
- path: "/ecosystem",
8831
- pattern: ["ecosystem"],
8832
- summary: "Get PM2 ecosystem config for agent services",
8833
- tags: ["Ecosystem"],
8834
- auth: { apiKey: true, agentId: true },
8835
- responses: {
8836
- 200: {
8837
- description: "PM2 ecosystem config",
8838
- schema: exports_external.object({ apps: exports_external.array(EcosystemAppSchema) })
8839
- },
8840
- 400: { description: "Missing X-Agent-ID" }
8841
- }
8842
- });
8843
- async function handleEcosystem(req, res, pathSegments, myAgentId) {
8844
- if (getEcosystem.match(req.method, pathSegments)) {
8845
- if (!myAgentId) {
8846
- jsonError(res, "Missing X-Agent-ID header", 400);
8847
- return true;
8848
- }
8849
- const services = await getServicesByAgentId(myAgentId);
8850
- const ecosystem = {
8851
- apps: services.filter((s) => s.script).map((s) => {
8852
- const app = {
8853
- name: s.name,
8854
- script: s.script
8855
- };
8856
- if (s.cwd)
8857
- app.cwd = s.cwd;
8858
- if (s.interpreter)
8859
- app.interpreter = s.interpreter;
8860
- if (s.args && s.args.length > 0)
8861
- app.args = s.args;
8862
- if (s.env && Object.keys(s.env).length > 0)
8863
- app.env = s.env;
8864
- if (s.port)
8865
- app.env = { ...app.env || {}, PORT: String(s.port) };
8866
- return app;
8867
- })
8868
- };
8869
- getEcosystem.respond(res, 200, ecosystem);
8870
- return true;
8871
- }
8872
- return false;
8873
- }
8874
-
8875
8859
  // src/http/events.ts
8876
8860
  init_zod();
8877
8861
  init_types();
@@ -9093,6 +9077,7 @@ declare module "swarm-extension" {
9093
9077
  | "linear"
9094
9078
  | "jira"
9095
9079
  | "comb"
9080
+ | "chat"
9096
9081
  | undefined;
9097
9082
  routingReason?:
9098
9083
  | "skill"
@@ -9206,7 +9191,8 @@ declare module "swarm-extension" {
9206
9191
  | "system"
9207
9192
  | "linear"
9208
9193
  | "jira"
9209
- | "comb";
9194
+ | "comb"
9195
+ | "chat";
9210
9196
  tags: string[];
9211
9197
  priority: number;
9212
9198
  dependsOn: string[];
@@ -9265,6 +9251,7 @@ declare module "swarm-extension" {
9265
9251
  resolvedModel?: string | undefined;
9266
9252
  modelSource?: string | undefined;
9267
9253
  modelAlias?: string | undefined;
9254
+ resolvedEffort?: "off" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
9268
9255
  scheduleId?: string | undefined;
9269
9256
  workflowRunId?: string | null | undefined;
9270
9257
  workflowRunStepId?: string | null | undefined;
@@ -9541,6 +9528,43 @@ declare module "swarm-extension" {
9541
9528
  kind: "broadcast";
9542
9529
  };
9543
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
+ }
9544
9568
  export type HeartbeatClassification = "no-session" | "stale-session" | "fresh-stalled";
9545
9569
  export type HeartbeatAction = "supersede-resume" | "fail" | "record";
9546
9570
  export interface HeartbeatRemediateEvent {
@@ -9585,6 +9609,18 @@ declare module "swarm-extension" {
9585
9609
  threadTs?: string;
9586
9610
  taskId?: string;
9587
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
+ }
9588
9624
  /**
9589
9625
  * A person answered an approval request. Fires for workflow and standalone
9590
9626
  * requests. Timeouts and cancellations do not emit it today.
@@ -9693,6 +9729,11 @@ declare module "swarm-extension" {
9693
9729
  modify: SlackRouteModify;
9694
9730
  result: PreResult<SlackRouteModify>;
9695
9731
  };
9732
+ "pre.chat.route": {
9733
+ event: ChatRouteEvent;
9734
+ modify: ChatRouteModify;
9735
+ result: PreResult<ChatRouteModify>;
9736
+ };
9696
9737
  "pre.heartbeat.remediate": {
9697
9738
  event: HeartbeatRemediateEvent;
9698
9739
  modify: HeartbeatRemediateModify;
@@ -9738,6 +9779,11 @@ declare module "swarm-extension" {
9738
9779
  modify: never;
9739
9780
  result: void;
9740
9781
  };
9782
+ "post.chat.message": {
9783
+ event: ChatMessageEvent;
9784
+ modify: never;
9785
+ result: void;
9786
+ };
9741
9787
  "post.approval.resolved": {
9742
9788
  event: ApprovalResolvedEvent;
9743
9789
  modify: never;
@@ -12794,6 +12840,203 @@ async function handleInboxState(req, res, pathSegments, queryParams) {
12794
12840
 
12795
12841
  // src/http/integrations.ts
12796
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
+ }
12797
13040
  // slack-manifest.json
12798
13041
  var slack_manifest_default = {
12799
13042
  display_information: {
@@ -12863,6 +13106,8 @@ var slack_manifest_default = {
12863
13106
  "app_mentions:read",
12864
13107
  "assistant:write",
12865
13108
  "channels:history",
13109
+ "channels:join",
13110
+ "channels:manage",
12866
13111
  "channels:read",
12867
13112
  "chat:write",
12868
13113
  "chat:write.customize",
@@ -12872,6 +13117,7 @@ var slack_manifest_default = {
12872
13117
  "files:write",
12873
13118
  "groups:history",
12874
13119
  "groups:read",
13120
+ "groups:write",
12875
13121
  "im:history",
12876
13122
  "im:read",
12877
13123
  "im:write",
@@ -12893,7 +13139,10 @@ var slack_manifest_default = {
12893
13139
  "message.groups",
12894
13140
  "message.im",
12895
13141
  "message.mpim",
12896
- "assistant_thread_started"
13142
+ "assistant_thread_started",
13143
+ "member_joined_channel",
13144
+ "channel_shared",
13145
+ "channel_unshared"
12897
13146
  ]
12898
13147
  },
12899
13148
  interactivity: {
@@ -12963,6 +13212,19 @@ var McpUserConfigSchema = exports_external.object({
12963
13212
  mcpUserUrl: exports_external.string()
12964
13213
  });
12965
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
+ });
12966
13228
  var claudeManagedTestRoute = route({
12967
13229
  method: "post",
12968
13230
  path: "/api/integrations/claude-managed/test",
@@ -13001,6 +13263,34 @@ var slackManifestRoute = route({
13001
13263
  200: { description: "Slack app manifest", schema: SlackManifestSchema }
13002
13264
  }
13003
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
+ });
13004
13294
  function createIntegrationsHandler(deps = {}) {
13005
13295
  const buildClient = deps.buildClient ?? ((apiKey) => new Anthropic({ apiKey }));
13006
13296
  return async function handleIntegrations(req, res, pathSegments, queryParams = new URLSearchParams) {
@@ -13011,6 +13301,26 @@ function createIntegrationsHandler(deps = {}) {
13011
13301
  slackManifestRoute.respond(res, 200, buildSlackManifest(parsed.query.name));
13012
13302
  return true;
13013
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
+ }
13014
13324
  if (mcpUserConfigRoute.match(req.method, pathSegments)) {
13015
13325
  const mcpBaseUrl = await resolveMcpBaseUrl();
13016
13326
  mcpUserConfigRoute.respond(res, 200, { mcpBaseUrl, mcpUserUrl: `${mcpBaseUrl}/mcp-user` });
@@ -13642,7 +13952,7 @@ var toRequestError = (e) => {
13642
13952
  return new RequestError(e.message, { cause: e });
13643
13953
  };
13644
13954
  var GlobalRequest = global.Request;
13645
- var Request = class extends GlobalRequest {
13955
+ var Request2 = class extends GlobalRequest {
13646
13956
  constructor(input, options) {
13647
13957
  if (typeof input === "object" && getRequestCache in input) {
13648
13958
  input = input[getRequestCache]();
@@ -13673,7 +13983,7 @@ var newRequestFromIncoming = (method, url, headers2, incoming, abortController)
13673
13983
  };
13674
13984
  if (method === "TRACE") {
13675
13985
  init.method = "GET";
13676
- const req = new Request(url, init);
13986
+ const req = new Request2(url, init);
13677
13987
  Object.defineProperty(req, "method", {
13678
13988
  get() {
13679
13989
  return "TRACE";
@@ -13710,7 +14020,7 @@ var newRequestFromIncoming = (method, url, headers2, incoming, abortController)
13710
14020
  init.body = Readable.toWeb(incoming);
13711
14021
  }
13712
14022
  }
13713
- return new Request(url, init);
14023
+ return new Request2(url, init);
13714
14024
  };
13715
14025
  var getRequestCache = Symbol("getRequestCache");
13716
14026
  var requestCache = Symbol("requestCache");
@@ -13776,7 +14086,7 @@ Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom")
13776
14086
  return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
13777
14087
  }
13778
14088
  });
13779
- Object.setPrototypeOf(requestPrototype, Request.prototype);
14089
+ Object.setPrototypeOf(requestPrototype, Request2.prototype);
13780
14090
  var newRequest = (incoming, defaultHostname) => {
13781
14091
  const req = Object.create(requestPrototype);
13782
14092
  req[incomingKey] = incoming;
@@ -13845,12 +14155,12 @@ var Response2 = class _Response {
13845
14155
  }
13846
14156
  }
13847
14157
  get headers() {
13848
- const cache = this[cacheKey];
13849
- if (cache) {
13850
- if (!(cache[2] instanceof Headers)) {
13851
- 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" });
13852
14162
  }
13853
- return cache[2];
14163
+ return cache2[2];
13854
14164
  }
13855
14165
  return this[getResponseCache]().headers;
13856
14166
  }
@@ -14138,9 +14448,9 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
14138
14448
  };
14139
14449
  var getRequestListener = (fetchCallback, options = {}) => {
14140
14450
  const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
14141
- if (options.overrideGlobalObjects !== false && global.Request !== Request) {
14451
+ if (options.overrideGlobalObjects !== false && global.Request !== Request2) {
14142
14452
  Object.defineProperty(global, "Request", {
14143
- value: Request
14453
+ value: Request2
14144
14454
  });
14145
14455
  Object.defineProperty(global, "Response", {
14146
14456
  value: Response2
@@ -15180,13 +15490,14 @@ async function handleMcp(req, res, transports, sessionActivity = {}, sessionAgen
15180
15490
  const configValue = configs.find((config) => config.key === "SCRIPTS_ONLY_MCP")?.value;
15181
15491
  const preloadEnabled = parseEnvFlag(configs.find((config) => config.key === "TASK_TOOL_PRELOAD_ENABLED")?.value ?? process.env.TASK_TOOL_PRELOAD_ENABLED, true);
15182
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] : [];
15183
15496
  if (preloadEnabled) {
15184
- const taskId = headerValue(req.headers["x-source-task-id"]);
15185
- const task = taskId ? await getTaskById(taskId) : undefined;
15186
- if (task?.agentId === agentId) {
15497
+ if (sourceTask?.agentId === agentId) {
15187
15498
  const manifestValue = configs.find((config) => config.key === "TASK_TOOL_MANIFESTS")?.value ?? process.env.TASK_TOOL_MANIFESTS ?? "{}";
15188
15499
  try {
15189
- preloadedTools = selectTaskTools(parseTaskToolManifest(manifestValue), task);
15500
+ preloadedTools = selectTaskTools(parseTaskToolManifest(manifestValue), sourceTask);
15190
15501
  } catch {
15191
15502
  console.warn("[MCP] Invalid TASK_TOOL_MANIFESTS; using ordinary tool discovery");
15192
15503
  }
@@ -15194,6 +15505,7 @@ async function handleMcp(req, res, transports, sessionActivity = {}, sessionAgen
15194
15505
  }
15195
15506
  const server = await createServer({
15196
15507
  preloadedTools,
15508
+ excludedTools,
15197
15509
  enabledTools: configs.find((config) => config.key === "SWARM_ENABLED_TOOLS")?.value ?? process.env.SWARM_ENABLED_TOOLS,
15198
15510
  scriptsOnly: resolveScriptsOnlyMode({
15199
15511
  env: process.env.SCRIPTS_ONLY_MCP,
@@ -15226,13 +15538,6 @@ init_zod();
15226
15538
  init_db3();
15227
15539
  init_types();
15228
15540
  init_constants();
15229
- init_env_flag();
15230
- function ssrfOptions() {
15231
- return {
15232
- allowPrivateHosts: isEnvFlagEnabled("MCP_OAUTH_ALLOW_PRIVATE_HOSTS", false),
15233
- allowInsecure: true
15234
- };
15235
- }
15236
15541
  function callbackRedirectUri() {
15237
15542
  return `${getPublicMcpBaseUrl()}/api/mcp-oauth/callback`;
15238
15543
  }
@@ -15296,11 +15601,11 @@ function scopesAreCovered(requested, registered) {
15296
15601
  function manualClientFromToken(token) {
15297
15602
  if (!token || token.clientSource !== "manual" || !token.dcrClientId)
15298
15603
  return null;
15299
- assertUrlSafe(token.resourceUrl, ssrfOptions());
15300
- assertUrlSafe(token.authorizeUrl, ssrfOptions());
15301
- assertUrlSafe(token.tokenUrl, ssrfOptions());
15604
+ assertUrlSafe(token.resourceUrl, mcpOAuthSsrfOptions());
15605
+ assertUrlSafe(token.authorizeUrl, mcpOAuthSsrfOptions());
15606
+ assertUrlSafe(token.tokenUrl, mcpOAuthSsrfOptions());
15302
15607
  if (token.revocationUrl)
15303
- assertUrlSafe(token.revocationUrl, ssrfOptions());
15608
+ assertUrlSafe(token.revocationUrl, mcpOAuthSsrfOptions());
15304
15609
  return {
15305
15610
  clientId: token.dcrClientId,
15306
15611
  clientSecret: token.dcrClientSecret,
@@ -15314,7 +15619,7 @@ function manualClientFromToken(token) {
15314
15619
  };
15315
15620
  }
15316
15621
  async function discoverForMcp(resourceUrl) {
15317
- assertUrlSafe(resourceUrl, ssrfOptions());
15622
+ assertUrlSafe(resourceUrl, mcpOAuthSsrfOptions());
15318
15623
  const prmd = await discoverProtectedResourceMetadata(resourceUrl);
15319
15624
  if (!prmd)
15320
15625
  return null;
@@ -20482,6 +20787,7 @@ init_resolver();
20482
20787
  init_session_templates();
20483
20788
  init_types();
20484
20789
  init_constants();
20790
+ init_node_env();
20485
20791
  init_request_auth_context();
20486
20792
 
20487
20793
  // src/http/tasks.ts
@@ -20490,9 +20796,47 @@ init_db3();
20490
20796
  init_steering();
20491
20797
  init_users();
20492
20798
  init_rbac();
20799
+ init_context_key();
20493
20800
  init_types();
20494
20801
  init_request_auth_context();
20495
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
20496
20840
  var AgentTaskSummarySchema = AgentTaskSchema.pick({
20497
20841
  id: true,
20498
20842
  key: true,
@@ -20516,6 +20860,7 @@ var AgentTaskSummarySchema = AgentTaskSchema.pick({
20516
20860
  modelSource: true,
20517
20861
  modelAlias: true,
20518
20862
  effort: true,
20863
+ resolvedEffort: true,
20519
20864
  provider: true,
20520
20865
  requestedByUserId: true,
20521
20866
  progress: true,
@@ -20659,6 +21004,9 @@ var createTask = route({
20659
21004
  400: {
20660
21005
  description: "Validation error, an unknown `model` (set `allowCustomModel` to store a custom id), or agentId/offeredTo targets an extension identity"
20661
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
+ },
20662
21010
  422: {
20663
21011
  description: "Task creation blocked by an extension",
20664
21012
  schema: exports_external.object({
@@ -20705,6 +21053,7 @@ var updateSession = route({
20705
21053
  claudeSessionId: exports_external.string().min(1),
20706
21054
  provider: ProviderNameSchema.exclude(["devin"]).optional(),
20707
21055
  model: exports_external.string().optional(),
21056
+ effort: ReasoningEffortSchema.nullable().optional(),
20708
21057
  providerMeta: exports_external.object({ transport: exports_external.enum(["cli", "sdk"]).optional() }).optional(),
20709
21058
  harnessVariant: exports_external.string().optional(),
20710
21059
  harnessVariantMeta: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
@@ -20919,7 +21268,10 @@ var listPausedTasks = route({
20919
21268
  200: {
20920
21269
  description: "Paused task list",
20921
21270
  schema: exports_external.object({
20922
- 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
+ }))
20923
21275
  })
20924
21276
  }
20925
21277
  }
@@ -21179,6 +21531,26 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
21179
21531
  return true;
21180
21532
  }
21181
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
+ }
21182
21554
  let assetKey;
21183
21555
  try {
21184
21556
  const inheritedKey = parentTask?.key;
@@ -21273,7 +21645,7 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
21273
21645
  const parsed = await updateSession.parse(req, res, pathSegments, queryParams);
21274
21646
  if (!parsed)
21275
21647
  return true;
21276
- 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);
21277
21649
  if (!task) {
21278
21650
  jsonError(res, "Task not found", 404);
21279
21651
  return true;
@@ -21713,10 +22085,14 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
21713
22085
  return true;
21714
22086
  }
21715
22087
  const pausedTasks = await getPausedTasksForAgent(myAgentId);
21716
- const tasks = await Promise.all(pausedTasks.map(async (task) => ({
21717
- ...task,
21718
- attachments: await getTaskAttachments(task.id)
21719
- })));
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
+ }));
21720
22096
  listPausedTasks.respond(res, 200, { tasks });
21721
22097
  return true;
21722
22098
  }
@@ -22222,10 +22598,6 @@ function withShareUrls(page) {
22222
22598
  app_url: `${getAppBaseUrl()}/pages/${page.slug}`
22223
22599
  };
22224
22600
  }
22225
- async function pageEditCounter(pageId) {
22226
- const versions = await getPageVersions(pageId);
22227
- return versions.length > 0 ? versions[0].version + 1 : 1;
22228
- }
22229
22601
  function defuseFeedbackTags(value) {
22230
22602
  return value.replace(/<(\/?page_feedback)/gi, "‹$1");
22231
22603
  }
@@ -22260,8 +22632,8 @@ function formatFeedbackComments(comments) {
22260
22632
  `);
22261
22633
  }
22262
22634
  function isDevRequest(req) {
22263
- if (false)
22264
- ;
22635
+ if (getNodeEnv() === "production")
22636
+ return false;
22265
22637
  const origin = req.headers.origin ?? "";
22266
22638
  return origin === "" || origin.startsWith("http://localhost") || origin.startsWith("http://127.0.0.1");
22267
22639
  }
@@ -22499,7 +22871,7 @@ async function handlePages(req, res, pathSegments, queryParams, myAgentId) {
22499
22871
  updatePageRoute.respond(res, 200, {
22500
22872
  id: updated.id,
22501
22873
  key: updated.key,
22502
- version: await pageEditCounter(updated.id)
22874
+ version: await getPageEditCounter(updated.id)
22503
22875
  });
22504
22876
  return true;
22505
22877
  }
@@ -22621,8 +22993,819 @@ ${defuseFeedbackTags(note)}
22621
22993
 
22622
22994
  // src/http/pages-public.ts
22623
22995
  init_zod();
22996
+ init_db3();
22624
22997
 
22625
- // src/artifact-sdk/feedback-overlay.ts
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
+ };
23058
+
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
22626
23809
  var PAGE_FEEDBACK_PARAM = "__swarm-feedback";
22627
23810
  function isPageFeedbackRequested(queryParams) {
22628
23811
  if (!queryParams.has(PAGE_FEEDBACK_PARAM))
@@ -23127,9 +24310,9 @@ function feedbackOverlayScripts(pageId) {
23127
24310
  }
23128
24311
 
23129
24312
  // src/http/pages-public.ts
23130
- init_db3();
23131
24313
  init_types();
23132
24314
  init_constants();
24315
+ init_node_env();
23133
24316
  init_secret_scrubber();
23134
24317
  var PublicPageJsonSchema = PageSchema.pick({
23135
24318
  id: true,
@@ -23329,7 +24512,7 @@ function getAppBaseUrl2() {
23329
24512
  }
23330
24513
  function buildCsp() {
23331
24514
  const configured = getConfiguredAppUrls();
23332
- const devFallbacks = [
24515
+ const devFallbacks = getNodeEnv() === "production" ? [] : [
23333
24516
  "http://localhost:5274",
23334
24517
  "http://localhost:5175",
23335
24518
  "http://127.0.0.1:5274",
@@ -23406,8 +24589,8 @@ function extractPasswordCandidate(req, queryParams) {
23406
24589
  return decoded.slice(colonIdx + 1);
23407
24590
  }
23408
24591
  function isLocalhostRequest(req) {
23409
- if (false)
23410
- ;
24592
+ if (getNodeEnv() === "production")
24593
+ return false;
23411
24594
  const origin = req.headers.origin ?? "";
23412
24595
  if (origin === "") {
23413
24596
  const rawHost = req.headers.host;
@@ -23694,21 +24877,11 @@ var PollTriggerAttachmentSchema = TaskAttachmentSchema.pick({
23694
24877
  mimeType: true,
23695
24878
  sizeBytes: true
23696
24879
  });
23697
- var PollRequestedBySchema = UserSchema.pick({
23698
- id: true,
23699
- name: true,
23700
- email: true,
23701
- role: true,
23702
- notes: true
23703
- }).extend({
23704
- id: exports_external.string().optional(),
23705
- comms: UserCommsPrefsSchema.optional()
23706
- });
23707
24880
  var PollTaskOfferedTriggerSchema = exports_external.object({
23708
24881
  type: exports_external.literal("task_offered"),
23709
24882
  taskId: exports_external.string(),
23710
24883
  task: AgentTaskSchema,
23711
- requestedBy: PollRequestedBySchema.optional()
24884
+ requestedBy: TaskRequestedBySchema.optional()
23712
24885
  });
23713
24886
  var PollTaskAssignedTriggerSchema = exports_external.object({
23714
24887
  type: exports_external.literal("task_assigned"),
@@ -23717,7 +24890,7 @@ var PollTaskAssignedTriggerSchema = exports_external.object({
23717
24890
  task: AgentTaskSchema.extend({
23718
24891
  attachments: exports_external.array(PollTriggerAttachmentSchema)
23719
24892
  }),
23720
- requestedBy: PollRequestedBySchema.optional()
24893
+ requestedBy: TaskRequestedBySchema.optional()
23721
24894
  });
23722
24895
  var PollUnreadMentionsTriggerSchema = exports_external.object({
23723
24896
  type: exports_external.literal("unread_mentions"),
@@ -23765,26 +24938,6 @@ var pollTriggers = route({
23765
24938
  });
23766
24939
  var CHANNEL_ACTIVITY_INTERVAL_MS = 60000;
23767
24940
  var lastChannelActivityCheckAt = 0;
23768
- function getRequesterNotes(notes) {
23769
- return typeof notes === "string" && notes.trim().length > 0 ? notes : undefined;
23770
- }
23771
- async function buildTriggerRequestedBy(task) {
23772
- const user = task.requestedByUserId ? await getUserById(task.requestedByUserId) : undefined;
23773
- if (user) {
23774
- return {
23775
- id: user.id,
23776
- name: user.name,
23777
- email: user.email,
23778
- role: user.role,
23779
- notes: getRequesterNotes(user.notes),
23780
- comms: getUserCommsPrefs(user)
23781
- };
23782
- }
23783
- if (task.slackUserId) {
23784
- return { name: renderIdentity(await resolveIdentity("slack", task.slackUserId)) };
23785
- }
23786
- return;
23787
- }
23788
24941
  async function attachmentsForTrigger(taskId) {
23789
24942
  return (await getTaskAttachments(taskId)).map((a) => ({
23790
24943
  id: a.id,
@@ -23794,11 +24947,21 @@ async function attachmentsForTrigger(taskId) {
23794
24947
  }));
23795
24948
  }
23796
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
+ };
23797
24957
  try {
23798
- return await recordClaimModelResolution(task, agent);
24958
+ return {
24959
+ ...cleared,
24960
+ ...await recordClaimModelResolution({ ...task, model: pin }, agent)
24961
+ };
23799
24962
  } catch (error) {
23800
24963
  console.warn(`[/api/poll] model resolution failed for task ${task.id}:`, error);
23801
- return {};
24964
+ return cleared;
23802
24965
  }
23803
24966
  }
23804
24967
  var commitCursorsRoute = route({
@@ -23883,7 +25046,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
23883
25046
  const claimedTask = await claimOfferedTask(firstOfferedTask.id, myAgentId);
23884
25047
  if (claimedTask) {
23885
25048
  await recordRuntimeTask(claimedTask.id);
23886
- const offeredRequestedBy = await buildTriggerRequestedBy(claimedTask);
25049
+ const offeredRequestedBy = await buildTaskRequestedBy(claimedTask);
23887
25050
  return {
23888
25051
  trigger: {
23889
25052
  type: "task_offered",
@@ -23963,7 +25126,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
23963
25126
  agentId: myAgentId
23964
25127
  });
23965
25128
  });
23966
- const assignedRequestedBy = await buildTriggerRequestedBy(pendingTask);
25129
+ const assignedRequestedBy = await buildTaskRequestedBy(pendingTask);
23967
25130
  const assignedTriggerSurface = await resolveTriggerSurface(pendingTask.id, pendingTask.source);
23968
25131
  return {
23969
25132
  trigger: {
@@ -24054,7 +25217,7 @@ async function handlePoll(req, res, pathSegments, queryParams, myAgentId) {
24054
25217
  agentId: myAgentId
24055
25218
  });
24056
25219
  });
24057
- const claimedRequestedBy = await buildTriggerRequestedBy(claimed);
25220
+ const claimedRequestedBy = await buildTaskRequestedBy(claimed);
24058
25221
  const claimedTriggerSurface = await resolveTriggerSurface(claimed.id, claimed.source);
24059
25222
  return {
24060
25223
  trigger: {
@@ -26308,6 +27471,7 @@ async function handleSchedules(req, res, pathSegments, queryParams, myAgentId) {
26308
27471
  init_zod();
26309
27472
  init_db3();
26310
27473
  init_rbac();
27474
+ init_secret_scrubber();
26311
27475
  var McpToolCallResultSchema = exports_external.object({
26312
27476
  content: exports_external.array(exports_external.object({ type: exports_external.string(), text: exports_external.string().optional() })),
26313
27477
  isError: exports_external.boolean().optional()
@@ -26341,6 +27505,35 @@ var mcpCallRoute = route({
26341
27505
  404: { description: "Script connection or agent not found" }
26342
27506
  }
26343
27507
  });
27508
+ var SqlQueryEnvelopeSchema = exports_external.union([
27509
+ exports_external.object({
27510
+ ok: exports_external.literal(true),
27511
+ rows: exports_external.array(exports_external.record(exports_external.string(), exports_external.unknown())),
27512
+ rowCount: exports_external.number(),
27513
+ truncated: exports_external.boolean()
27514
+ }),
27515
+ exports_external.object({ ok: exports_external.literal(false), error: exports_external.string() })
27516
+ ]);
27517
+ var sqlQueryRoute = route({
27518
+ method: "post",
27519
+ path: "/api/script-connections/{id}/sql-query",
27520
+ pattern: ["api", "script-connections", null, "sql-query"],
27521
+ summary: "Run one read-only query on a SQL script connection",
27522
+ tags: ["Script Connections"],
27523
+ auth: { apiKey: true, agentId: true },
27524
+ rbac: { permission: "script-connection.invoke" },
27525
+ params: exports_external.object({ id: exports_external.string().uuid() }),
27526
+ body: exports_external.object({
27527
+ sql: exports_external.string().min(1).max(1e5),
27528
+ params: exports_external.array(exports_external.unknown()).max(100).optional()
27529
+ }),
27530
+ responses: {
27531
+ 200: { description: "Query rows or a scrubbed error", schema: SqlQueryEnvelopeSchema },
27532
+ 400: { description: "Invalid SQL connection or request" },
27533
+ 403: { description: "Not allowed to invoke this SQL connection" },
27534
+ 404: { description: "Script connection or agent not found" }
27535
+ }
27536
+ });
26344
27537
  function connectionScopeMatches(connection, agentId, syntheticPrincipal) {
26345
27538
  if (connection.scope === "global")
26346
27539
  return true;
@@ -26354,9 +27547,10 @@ function isSyntheticScriptPrincipal(agentId) {
26354
27547
  return agentId === "schedule" || agentId === "workflow";
26355
27548
  }
26356
27549
  async function handleScriptConnectionProxy(req, res, pathSegments, queryParams, agentId) {
26357
- if (!mcpCallRoute.match(req.method, pathSegments))
27550
+ const isSql = sqlQueryRoute.match(req.method, pathSegments);
27551
+ if (!isSql && !mcpCallRoute.match(req.method, pathSegments))
26358
27552
  return false;
26359
- const parsed = await mcpCallRoute.parse(req, res, pathSegments, queryParams);
27553
+ const parsed = isSql ? await sqlQueryRoute.parse(req, res, pathSegments, queryParams) : await mcpCallRoute.parse(req, res, pathSegments, queryParams);
26360
27554
  if (!parsed)
26361
27555
  return true;
26362
27556
  if (!agentId) {
@@ -26388,14 +27582,25 @@ async function handleScriptConnectionProxy(req, res, pathSegments, queryParams,
26388
27582
  jsonError(res, "Script connection is disabled", 403);
26389
27583
  return true;
26390
27584
  }
26391
- if (connection.kind !== "mcp") {
26392
- jsonError(res, "Script connection is not an MCP connection", 400);
27585
+ if (connection.kind !== (isSql ? "sql" : "mcp")) {
27586
+ jsonError(res, `Script connection is not ${isSql ? "a SQL" : "an MCP"} connection`, 400);
26393
27587
  return true;
26394
27588
  }
26395
27589
  if (!connectionScopeMatches(connection, agentId, syntheticPrincipal)) {
26396
27590
  jsonError(res, "Script connection is not available to this agent", 403);
26397
27591
  return true;
26398
27592
  }
27593
+ if ("sql" in parsed.body) {
27594
+ try {
27595
+ const dsn = await resolveSqlDsn(connection, agentId);
27596
+ const result = await runReadOnlyQuery(dsn, parsed.body.sql, parsed.body.params);
27597
+ sqlQueryRoute.respond(res, 200, { ok: true, ...result });
27598
+ } catch (err) {
27599
+ const error = scrubSecrets(err instanceof Error ? err.message : String(err));
27600
+ sqlQueryRoute.respond(res, 200, { ok: false, error });
27601
+ }
27602
+ return true;
27603
+ }
26399
27604
  if (!connection.mcpServerId) {
26400
27605
  jsonError(res, "Script MCP connection is missing mcpServerId", 400);
26401
27606
  return true;
@@ -26424,7 +27629,7 @@ init_request_auth_context();
26424
27629
  init_secret_scrubber();
26425
27630
  var providerSchema = exports_external.string().min(1).max(255).regex(/^[A-Za-z0-9_-]+$/);
26426
27631
  var scopeSchema = exports_external.enum(["global", "agent", "repo"]);
26427
- var connectionKindSchema = exports_external.enum(["openapi", "graphql", "mcp"]);
27632
+ var connectionKindSchema = exports_external.enum(["openapi", "graphql", "mcp", "sql"]);
26428
27633
  var idParamsSchema2 = exports_external.object({ id: exports_external.string().uuid() });
26429
27634
  var providerParamsSchema = exports_external.object({ provider: providerSchema });
26430
27635
  var oauthResourceIdParamsSchema = exports_external.object({ id: exports_external.string().min(1).max(255) });
@@ -26469,7 +27674,8 @@ var upsertConnectionBodySchema = exports_external.discriminatedUnion("kind", [
26469
27674
  connectionBaseBodySchema.extend({
26470
27675
  kind: exports_external.literal("mcp"),
26471
27676
  mcpServerId: exports_external.string().uuid()
26472
- })
27677
+ }),
27678
+ connectionBaseBodySchema.extend({ kind: exports_external.literal("sql"), dsn: SqlDsnInputSchema.optional() })
26473
27679
  ]);
26474
27680
  var disableConnectionBodySchema = exports_external.object({ enabled: exports_external.boolean() });
26475
27681
  var credentialBindingBodySchema = exports_external.object({
@@ -26532,7 +27738,7 @@ async function countBindingType(type) {
26532
27738
  return (await listRelationalCredentialBindings({ includeInactive: true })).filter((binding) => _resolveIntegrationType(bindingIntegrationProvider(binding)) === type).length;
26533
27739
  }
26534
27740
  var connectionAuthTypeResponseSchema = exports_external.enum(["none", "bearer", "header", "query", "oauth"]);
26535
- var connectionRecordKindSchema = exports_external.enum(["raw", "openapi", "mcp", "graphql"]);
27741
+ var connectionRecordKindSchema = exports_external.enum(["raw", "openapi", "mcp", "graphql", "sql"]);
26536
27742
  var bindingSummarySchema = exports_external.object({
26537
27743
  id: exports_external.string(),
26538
27744
  configKey: exports_external.string(),
@@ -27872,6 +29078,7 @@ async function handleScriptConnections(req, res, pathSegments, queryParams, agen
27872
29078
  openapiSpecEtag: reuseExistingOpenapiSpec ? existingOpenapiConnection?.openapiSpecEtag : undefined,
27873
29079
  openapiSpecFetchedAt: reuseExistingOpenapiSpec ? existingOpenapiConnection?.openapiSpecFetchedAt : undefined,
27874
29080
  mcpServerId: parsed.body.kind === "mcp" ? parsed.body.mcpServerId : null,
29081
+ sqlDsn: parsed.body.kind === "sql" ? parsed.body.dsn : undefined,
27875
29082
  enabled,
27876
29083
  agentId,
27877
29084
  userId
@@ -29546,6 +30753,7 @@ async function handleScripts(req, res, pathSegments, queryParams, agentId) {
29546
30753
  runtimeInstanceId,
29547
30754
  egressSecrets: credentials.egressSecrets,
29548
30755
  failedBindings: credentials.failedBindings,
30756
+ userConfig: credentials.userConfig,
29549
30757
  apiConnections: getScriptApiConnectionDescriptors({ agentId: agent.id }),
29550
30758
  mcpConnections: getScriptMcpConnectionDescriptors({ agentId: agent.id })
29551
30759
  });
@@ -29961,8 +31169,8 @@ async function recomputeSessionCost(input, lookupRate) {
29961
31169
  modelBreakdown
29962
31170
  };
29963
31171
  }
29964
- if ((input.provider === "amp" || input.provider === "grok") && input.harnessCostUsd > 0) {
29965
- const priced = await recomputeSessionCost({ ...input, harnessCostUsd: 0 }, lookupRate);
31172
+ if ((input.provider === "amp" || input.provider === "grok" || input.harnessCostBilled) && input.harnessCostUsd > 0) {
31173
+ const priced = await recomputeSessionCost({ ...input, harnessCostUsd: 0, harnessCostBilled: false }, lookupRate);
29966
31174
  return {
29967
31175
  totalCostUsd: input.harnessCostUsd,
29968
31176
  costSource: "harness",
@@ -30144,6 +31352,7 @@ var createSessionCostRoute = route({
30144
31352
  sessionId: exports_external.string().min(1),
30145
31353
  agentId: exports_external.string().min(1),
30146
31354
  totalCostUsd: exports_external.number(),
31355
+ harnessCostBilled: exports_external.boolean().optional(),
30147
31356
  taskId: exports_external.string().optional(),
30148
31357
  inputTokens: exports_external.number().int().nonnegative().optional(),
30149
31358
  outputTokens: exports_external.number().int().nonnegative().optional(),
@@ -30297,6 +31506,7 @@ async function handleSessionData(req, res, pathSegments, queryParams, _myAgentId
30297
31506
  provider: parsed.body.provider,
30298
31507
  model,
30299
31508
  harnessCostUsd: parsed.body.totalCostUsd,
31509
+ harnessCostBilled: parsed.body.harnessCostBilled,
30300
31510
  inputTokens,
30301
31511
  outputTokens,
30302
31512
  cacheReadTokens: cachedInputTokens,
@@ -32040,21 +33250,6 @@ var getMetrics = route({
32040
33250
  200: { description: "Swarm metrics counts", schema: SwarmMetricsSchema }
32041
33251
  }
32042
33252
  });
32043
- var listServices = route({
32044
- method: "get",
32045
- path: "/api/services",
32046
- pattern: ["api", "services"],
32047
- summary: "List all registered services",
32048
- tags: ["Stats"],
32049
- query: exports_external.object({
32050
- status: exports_external.string().optional(),
32051
- agentId: exports_external.string().optional(),
32052
- name: exports_external.string().optional()
32053
- }),
32054
- responses: {
32055
- 200: { description: "Service list", schema: exports_external.object({ services: exports_external.array(ServiceSchema) }) }
32056
- }
32057
- });
32058
33253
  var listScheduledTasks = route({
32059
33254
  method: "get",
32060
33255
  path: "/api/scheduled-tasks",
@@ -32140,18 +33335,6 @@ async function handleStats(req, res, pathSegments, queryParams, myAgentId) {
32140
33335
  });
32141
33336
  return true;
32142
33337
  }
32143
- if (listServices.match(req.method, pathSegments)) {
32144
- const parsed = await listServices.parse(req, res, pathSegments, queryParams);
32145
- if (!parsed)
32146
- return true;
32147
- const services = await getAllServices({
32148
- status: parsed.query.status || undefined,
32149
- agentId: parsed.query.agentId || undefined,
32150
- name: parsed.query.name || undefined
32151
- });
32152
- listServices.respond(res, 200, { services });
32153
- return true;
32154
- }
32155
33338
  if (listScheduledTasks.match(req.method, pathSegments)) {
32156
33339
  const parsed = await listScheduledTasks.parse(req, res, pathSegments, queryParams);
32157
33340
  if (!parsed)
@@ -34297,6 +35480,8 @@ async function routeKapsoInbound(payload) {
34297
35480
  }
34298
35481
 
34299
35482
  // src/http/webhooks.ts
35483
+ init_constants();
35484
+ init_secret_scrubber();
34300
35485
  init_event_bus();
34301
35486
  var WebhookDispatchResultSchema = exports_external.object({
34302
35487
  created: exports_external.boolean(),
@@ -34392,6 +35577,57 @@ var kapsoWebhook = route({
34392
35577
  503: { description: "Kapso integration not configured" }
34393
35578
  }
34394
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
+ }
34395
35631
  function logKapsoAckResult(action, result) {
34396
35632
  if (result.ok)
34397
35633
  return;
@@ -34475,7 +35711,8 @@ async function handleWebhooks(req, res, pathSegments) {
34475
35711
  res.end(JSON.stringify({ error: "Invalid JSON body" }));
34476
35712
  return true;
34477
35713
  }
34478
- console.log(`[GitHub] Received ${eventType} event`);
35714
+ const deliveryId = req.headers["x-github-delivery"];
35715
+ console.log(`[GitHub] Received ${eventType} event (delivery ${deliveryId ?? "unknown"})`);
34479
35716
  let result = { created: false };
34480
35717
  try {
34481
35718
  result = await runBlockableHandler("GitHub", async () => {
@@ -34549,13 +35786,13 @@ async function handleWebhooks(req, res, pathSegments) {
34549
35786
  }
34550
35787
  githubWebhook.respond(res, 200, result);
34551
35788
  } catch (err) {
34552
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34553
- 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}`);
34554
35791
  if (err instanceof Error && err.stack) {
34555
35792
  console.error(err.stack);
34556
35793
  }
34557
35794
  res.writeHead(500, { "Content-Type": "application/json" });
34558
- res.end(JSON.stringify({ error: "Internal server error", message: errorMessage2 }));
35795
+ res.end(JSON.stringify({ error: "Internal server error", message: errorMessage3 }));
34559
35796
  }
34560
35797
  return true;
34561
35798
  }
@@ -34663,8 +35900,8 @@ async function handleWebhooks(req, res, pathSegments) {
34663
35900
  }
34664
35901
  gitlabWebhook.respond(res, 200, result);
34665
35902
  } catch (err) {
34666
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34667
- 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}`);
34668
35905
  if (err instanceof Error && err.stack) {
34669
35906
  console.error(err.stack);
34670
35907
  }
@@ -34708,6 +35945,16 @@ async function handleWebhooks(req, res, pathSegments) {
34708
35945
  return await handlePullRequestCreated(body);
34709
35946
  case "ms.vss-code.git-pullrequest-comment-event":
34710
35947
  return await handlePullRequestCommented(body);
35948
+ case "workitem.created":
35949
+ return await handleWorkItemCreated(body);
35950
+ case "workitem.updated":
35951
+ return await handleWorkItemUpdated(body);
35952
+ case "workitem.commented":
35953
+ return await handleWorkItemCommented(body);
35954
+ case "workitem.deleted":
35955
+ return await handleWorkItemDeleted(body);
35956
+ case "workitem.restored":
35957
+ return await handleWorkItemRestored(body);
34711
35958
  default:
34712
35959
  console.log(`[AzureDevOps] Ignoring unsupported event type: ${eventType}`);
34713
35960
  return { created: false };
@@ -34744,8 +35991,8 @@ async function handleWebhooks(req, res, pathSegments) {
34744
35991
  }
34745
35992
  azureDevOpsWebhook.respond(res, 200, result);
34746
35993
  } catch (err) {
34747
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34748
- 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}`);
34749
35996
  if (err instanceof Error && err.stack) {
34750
35997
  console.error(err.stack);
34751
35998
  }
@@ -34813,8 +36060,8 @@ async function handleWebhooks(req, res, pathSegments) {
34813
36060
  console.log(`[AgentMail] Ignoring event type: ${payload.event_type}`);
34814
36061
  }
34815
36062
  } catch (err) {
34816
- const errorMessage2 = err instanceof Error ? err.message : String(err);
34817
- 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}`);
34818
36065
  if (err instanceof Error && err.stack) {
34819
36066
  console.error(err.stack);
34820
36067
  }
@@ -34874,16 +36121,84 @@ async function handleWebhooks(req, res, pathSegments) {
34874
36121
  }
34875
36122
  kapsoWebhook.respond(res, 200, { received: true, routing: routing.kind });
34876
36123
  } catch (err) {
34877
- const errorMessage2 = err instanceof Error ? err.message : String(err);
36124
+ const errorMessage3 = err instanceof Error ? err.message : String(err);
34878
36125
  if (err instanceof WebhookError) {
34879
- console.warn(`[Kapso] Workflow dispatch rejected: ${errorMessage2}`);
36126
+ console.warn(`[Kapso] Workflow dispatch rejected: ${errorMessage3}`);
34880
36127
  } else {
34881
- console.error(`[Kapso] Error handling inbound event: ${errorMessage2}`);
36128
+ console.error(`[Kapso] Error handling inbound event: ${errorMessage3}`);
34882
36129
  }
34883
36130
  kapsoWebhook.respond(res, 200, { received: true, routing: "error" });
34884
36131
  }
34885
36132
  return true;
34886
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
+ }
34887
36202
  return false;
34888
36203
  }
34889
36204
 
@@ -35906,6 +37221,7 @@ async function handleX(req, res, pathSegments) {
35906
37221
  timeoutMs,
35907
37222
  egressSecrets: credentials.egressSecrets,
35908
37223
  failedBindings: credentials.failedBindings,
37224
+ userConfig: credentials.userConfig,
35909
37225
  apiConnections: getScriptApiConnectionDescriptors({ agentId: endpoint.agentId }),
35910
37226
  mcpConnections: getScriptMcpConnectionDescriptors({ agentId: endpoint.agentId })
35911
37227
  });
@@ -36054,7 +37370,6 @@ var httpServer = createHttpServer(async (req, res) => {
36054
37370
  () => handleAgentRegister(req, res, pathSegments, myAgentId),
36055
37371
  () => handlePoll(req, res, pathSegments, queryParams, myAgentId),
36056
37372
  () => handleSessionData(req, res, pathSegments, queryParams, myAgentId),
36057
- () => handleEcosystem(req, res, pathSegments, myAgentId),
36058
37373
  () => handleTrackers(req, res, pathSegments),
36059
37374
  () => handleWebhooks(req, res, pathSegments),
36060
37375
  () => handleAgentsRest(req, res, pathSegments, queryParams, myAgentId),
@@ -36146,7 +37461,7 @@ var httpServer = createHttpServer(async (req, res) => {
36146
37461
  });
36147
37462
  });
36148
37463
  var detachRealtime = attachRealtimeTransport(httpServer);
36149
- var { attachControllerTransport } = await import("./controllers-connect-y07cqcvy.js");
37464
+ var { attachControllerTransport } = await import("./controllers-connect-kwpvj3rf.js");
36150
37465
  var detachControllers = attachControllerTransport(httpServer);
36151
37466
  var stopWorkerNudges = startWorkerNudgeListener();
36152
37467
  var stopRoomDeletion = realtimeBus.subscribe("room:namespace-deleted", (namespace) => {
@@ -36175,7 +37490,7 @@ async function shutdown() {
36175
37490
  sessionsProcessed: getServerSessionsProcessed()
36176
37491
  });
36177
37492
  if (hasCapability("scheduling")) {
36178
- const { stopScheduler } = await import("./index-e0snym4t.js");
37493
+ const { stopScheduler } = await import("./index-7ep4gzdk.js");
36179
37494
  stopScheduler();
36180
37495
  }
36181
37496
  stopHeartbeat();
@@ -36185,8 +37500,9 @@ async function shutdown() {
36185
37500
  await drainApi();
36186
37501
  await stopScriptRunSupervisor();
36187
37502
  await stopSlackApp();
37503
+ await stopChatSdk();
36188
37504
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
36189
- const { stopOAuthKeepalive } = await import("./keepalive-jekc896t.js");
37505
+ const { stopOAuthKeepalive } = await import("./keepalive-be9vwy5h.js");
36190
37506
  await stopOAuthKeepalive();
36191
37507
  }
36192
37508
  stopOAuthPendingGc();
@@ -36266,15 +37582,15 @@ try {
36266
37582
  console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
36267
37583
  }
36268
37584
  try {
36269
- const { ensurePricingSeeded } = await import("./boot-seeds-8q637aew.js");
37585
+ const { ensurePricingSeeded } = await import("./boot-seeds-kwjq4d2z.js");
36270
37586
  ensurePricingSeeded();
36271
- const { startPricingRefreshLoop } = await import("./pricing-refresh-s52nsa5q.js");
37587
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-qb0rv0ap.js");
36272
37588
  startPricingRefreshLoop();
36273
37589
  } catch (err) {
36274
37590
  console.error("[startup] Failed to seed pricing rows:", err);
36275
37591
  }
36276
37592
  try {
36277
- const { ensureRbacSeeded } = await import("./boot-seeds-8q637aew.js");
37593
+ const { ensureRbacSeeded } = await import("./boot-seeds-kwjq4d2z.js");
36278
37594
  ensureRbacSeeded();
36279
37595
  } catch (err) {
36280
37596
  console.error("[startup] Failed to sync RBAC seed rows:", err);
@@ -36282,7 +37598,7 @@ try {
36282
37598
  throw err;
36283
37599
  }
36284
37600
  try {
36285
- const { runAllSeeders } = await import("./index-6ksewd5y.js");
37601
+ const { runAllSeeders } = await import("./index-s2wxgzr0.js");
36286
37602
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
36287
37603
  } catch (err) {
36288
37604
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -36330,6 +37646,9 @@ httpServer.listen(port, async () => {
36330
37646
  } catch (err) {
36331
37647
  console.error("[Slack] Failed to start, continuing boot without Slack:", err);
36332
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
+ });
36333
37652
  startQueueStallAlarm();
36334
37653
  initGitHub();
36335
37654
  initGitLab();
@@ -36340,39 +37659,39 @@ httpServer.listen(port, async () => {
36340
37659
  await initWorkflows();
36341
37660
  await startScriptRunSupervisor(getMcpBaseUrl());
36342
37661
  if (hasCapability("scheduling")) {
36343
- const { startScheduler } = await import("./index-e0snym4t.js");
36344
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-vm3bm9t7.js");
37662
+ const { startScheduler } = await import("./index-7ep4gzdk.js");
37663
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-rmpw9a8q.js");
36345
37664
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
36346
37665
  startScheduler(getExecutorRegistry2(), intervalMs, {
36347
37666
  runId: globalState.__runId
36348
37667
  });
36349
37668
  }
36350
37669
  if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
36351
- const { startHeartbeat } = await import("./index-tsszt7g9.js");
37670
+ const { startHeartbeat } = await import("./index-v1v6n7hg.js");
36352
37671
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
36353
37672
  startHeartbeat(heartbeatMs);
36354
37673
  }
36355
37674
  startPoolRouting();
36356
37675
  startRuntimeSupervisor();
36357
37676
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
36358
- const { startOAuthKeepalive } = await import("./keepalive-jekc896t.js");
37677
+ const { startOAuthKeepalive } = await import("./keepalive-be9vwy5h.js");
36359
37678
  startOAuthKeepalive();
36360
37679
  }
36361
37680
  if (process.env.OAUTH_REFRESH_SWEEP_DISABLE !== "true") {
36362
- const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-5gb36kn8.js");
37681
+ const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-cpdnfwdj.js");
36363
37682
  startOAuthRefreshSweep();
36364
37683
  }
36365
37684
  startOAuthPendingGc();
36366
37685
  await startMemoryGc();
36367
37686
  await startDbRetention();
36368
37687
  startHumanFreeDrain();
36369
- import("./boot-reembed-1de4f4aj.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
37688
+ import("./boot-reembed-5c2z0mbe.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
36370
37689
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
36371
37690
  });
36372
- import("./boot-reembed-4ymn9atn.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
37691
+ import("./boot-reembed-j8xa181e.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
36373
37692
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
36374
37693
  });
36375
- import("./boot-scrub-sweep-adhk1s8c.js").then(({ runBootScrubSweep }) => runBootScrubSweep()).catch((err) => {
37694
+ import("./boot-scrub-sweep-hnkn3rgt.js").then(({ runBootScrubSweep }) => runBootScrubSweep()).catch((err) => {
36376
37695
  console.error("[boot-scrub-sweep] startup scrub failed (non-fatal):", err);
36377
37696
  });
36378
37697
  }).on("error", (err) => {