@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
@@ -22,8 +22,8 @@ rate by hand should also update this file.
22
22
  - **Runtime module**: `src/be/models-catalog.ts`; route in
23
23
  `src/http/models-catalog.ts`.
24
24
  - Every successful models.dev fetch in the runtime refresh above also updates
25
- an in-memory slim catalog (openrouter / anthropic / openai / amazon-bedrock
26
- only, picker-relevant fields only). The UI model picker
25
+ an in-memory slim catalog (openrouter / anthropic / openai / amazon-bedrock /
26
+ nan / helmcode only, picker-relevant fields only). The UI model picker
27
27
  (`apps/ui/src/lib/agent-runtime-models.ts` via `useModelsCatalog()`) prefers
28
28
  this over its build-time snapshot, so new models appear without a deploy.
29
29
  - Pinned limited-availability entries (`PINNED_MODELSDEV_ENTRIES`) are
@@ -49,7 +49,10 @@ rate by hand should also update this file.
49
49
  shortname forms, so they're projected under `provider='pi'` as well.
50
50
  - OpenAI models → rows under `provider='codex'`.
51
51
  - OpenRouter models → rows under `provider='opencode'`, `provider='pi'` and
52
- `provider='dsh'` (dsh strips `openrouter/` at lookup). Any `google/...`
52
+ `provider='dsh'` (dsh strips `openrouter/` at lookup). These are
53
+ OpenRouter's model-level list price, the cheapest endpoint's rate, so they
54
+ under-price a request routed to a dearer endpoint. opencode posts
55
+ OpenRouter's billed `usage.cost` instead when it has it. Any `google/...`
53
56
  row additionally gets projected under `provider='gemini'` (both the
54
57
  stripped name and the full `google/...` id) so internal-ai callers find
55
58
  a hit either way.
@@ -81,6 +84,25 @@ rate by hand should also update this file.
81
84
  `inputTokens`, clamped to zero, so fresh input is priced separately.
82
85
  Cursor's own models are not in models.dev: see
83
86
  `CURSOR_FIRST_PARTY_PRICING` below.
87
+ - OpenAI-compatible registry providers: NaN models (models.dev `nan`
88
+ section) and Helmcode models (the registry-synthesized `helmcode`
89
+ section, below) → rows under `provider='pi'` and
90
+ `provider='opencode'`, keyed `nan/<id>` and `helmcode/<id>`, at $0 input
91
+ and $0 output. Both providers bill a flat rate per key, so a session's
92
+ marginal cost is $0. `buildModelsDevSeedRows()` projects them, so the rows
93
+ land at boot seed and on refresh, and sessions record $0 with
94
+ `costSource: "pricing-table"` rather than `unpriced`.
95
+
96
+ - **Registry-synthesized `helmcode` section**: Helmcode is not on models.dev.
97
+ Its five agent models (`deepseek-v4-flash`, `glm5.3`, `glm5.3-flash`,
98
+ `qwen3.6`, `gemma4`) live in the provider registry
99
+ (`packages/model-catalog/src/openai-compatible-providers.ts`,
100
+ `catalog: "registry"`). `withRegistryCatalogSections` adds the section,
101
+ at $0, to the snapshot loader (`loadModelsDevCache`), the worker runtime
102
+ catalog and the dashboard bundle, and the live catalog refills it
103
+ (`setLiveModelsCatalog`). Model limits are copied from Helmcode's own
104
+ opencode and pi config pages. Helmcode's resold Claude, GPT and Gemini
105
+ models are not included.
84
106
 
85
107
  - **Snapshot refresh procedure**:
86
108
  - Run `bun run scripts/refresh-modelsdev-pricing.ts` (Phase 2 — adds the
@@ -164,6 +186,18 @@ and heartbeat-classified roots are omitted, and the metrics remain separate.
164
186
  scheduled increase to $3/M input and $15/M output on 2026-09-01. Claude
165
187
  Code's bundled local rate table may be stale-high, so treat its reported USD
166
188
  as advisory and use the server-recomputed row for the canonical total.
189
+ - **Claude 5.5 cache reads:** Opus 5.5 and Sonnet 5.5 cache hits cost 0.05x
190
+ input ($0.20/M and $0.10/M), not the usual 0.1x. Claude Code builds in use
191
+ around 2026-10-09 still priced Sonnet 5.5 hits at $0.20/M, so their
192
+ `harnessCostUsd` runs high by `cacheReadTokens × $0.10/M`.
193
+ - **Claude Haiku 5.5 context tier:** a request whose prompt (input + cache
194
+ reads + cache writes) is over 100k tokens bills every class at 5x: $0.50/M
195
+ input, $0.05/M cache hit, $0.625/M 5m write, $1/M 1h write, $2.50/M output.
196
+ It is the only Claude 5.x model with a long-context tier; the others bill the
197
+ full 1M window at standard rates. The recompute prices Haiku 5.5 at the base
198
+ tier, so sessions with over-100k requests under-count, and the harness total
199
+ is the closer figure for them. Same per-request accounting gap as GPT-5.6
200
+ below.
167
201
  - **GPT-5.6 context tier:** above 272k context, the GPT-5.6 family bills
168
202
  2× input/cache rates and 1.5× output rates. The current recompute receives
169
203
  aggregate session token counts, not enough per-request context information
@@ -245,3 +245,30 @@ export function applyReasoningEffort(
245
245
  }
246
246
  }
247
247
  }
248
+
249
+ const REASONING_HARNESSES: ReadonlySet<string> = new Set<ReasoningHarness>([
250
+ "claude",
251
+ "codex",
252
+ "pi",
253
+ "opencode",
254
+ "dsh",
255
+ "cursor",
256
+ "amp",
257
+ "grok",
258
+ ]);
259
+
260
+ /**
261
+ * The effort a session on this harness and model actually runs at: `level`
262
+ * when the adapter applies it, null when it is unset or dropped (the harness
263
+ * default applies). Same decision the adapters make in `applyReasoningEffort`.
264
+ */
265
+ export function effectiveReasoningEffort(
266
+ harness: string,
267
+ model: string,
268
+ level: ReasoningEffort | undefined,
269
+ ): ReasoningEffort | null {
270
+ if (!level || !REASONING_HARNESSES.has(harness)) return null;
271
+ return applyReasoningEffort(harness as ReasoningHarness, model, level).kind === "noop"
272
+ ? null
273
+ : level;
274
+ }
@@ -15,6 +15,11 @@ export interface CostData {
15
15
  taskId?: string;
16
16
  agentId: string;
17
17
  totalCostUsd: number;
18
+ /**
19
+ * `totalCostUsd` is what the model provider charged, not a token estimate,
20
+ * so it wins over the pricing table (opencode on OpenRouter).
21
+ */
22
+ harnessCostBilled?: boolean;
18
23
  inputTokens?: number;
19
24
  outputTokens?: number;
20
25
  cacheReadTokens?: number;
@@ -28,7 +33,11 @@ export interface CostData {
28
33
  cacheWrite1hTokens?: number;
29
34
  /** Migration 063: codex reasoning_output_tokens (and similar) for reasoning models. */
30
35
  reasoningOutputTokens?: number;
31
- /** Migration 063: claude extended-thinking tokens from CLI's `usage.thinking_input_tokens`. */
36
+ /**
37
+ * Migration 063: claude extended-thinking tokens from the result line's
38
+ * `usage.output_tokens_details.thinking_tokens`. Informational: they are a
39
+ * subset of `outputTokens` and already priced there.
40
+ */
32
41
  thinkingTokens?: number;
33
42
  /** Complete per-model usage, including sidechain/subagent tokens when available. */
34
43
  models?: CostModelUsage[];
@@ -258,7 +267,7 @@ export interface ProviderTraits {
258
267
  * agent never learns they exist. Defaults to true when omitted.
259
268
  */
260
269
  nativeSkillDiscovery?: boolean;
261
- /** Provider runs in the local Docker container with /workspace, identity files, agent-fs, PM2, etc. */
270
+ /** Provider runs in the local Docker container with /workspace, identity files, agent-fs, etc. */
262
271
  hasLocalEnvironment: boolean;
263
272
  /** Live steering modes supported by this provider. Absent means none. */
264
273
  steerModes?: SteerMode[];
@@ -206,8 +206,9 @@ const memoryDelete: LegacyRule = {
206
206
  };
207
207
 
208
208
  /**
209
- * task.fs.mutate — operator OR user OR lead OR task-assignee OR task-creator
210
- * (src/http/fs.ts canMutateTask). Order-independent OR: today's early
209
+ * task.fs.mutate and task.parent.attach: operator OR user OR lead OR
210
+ * task-assignee OR task-creator (src/http/fs.ts canMutateTask; send-task and
211
+ * POST /api/tasks for a parentTaskId). Order-independent OR: today's early
211
212
  * operator/user returns short-circuit before agent identity, but no input
212
213
  * satisfies one branch while failing another, so a flat OR is equivalent
213
214
  * (plan Appendix A row 36 note).
@@ -276,6 +277,7 @@ export const LEGACY_POLICY = {
276
277
  "task.steer.own": requesterOwnsTask,
277
278
  "task.action.own": requesterOwnsTask,
278
279
  "task.fs.mutate": taskFsMutate,
280
+ "task.parent.attach": taskFsMutate,
279
281
  "task.progress.write": taskProgressWrite,
280
282
  "favorite.write.own": anyAuthenticated,
281
283
  "memory.learning.inject": leadOnly,
@@ -286,6 +288,10 @@ export const LEGACY_POLICY = {
286
288
  "channel.delete": leadOnly,
287
289
  "repo.merge-policy.write": leadOrOperatorOrUser,
288
290
  "integration.kapso.manage": leadOnly,
291
+ "integration.chat.manage": leadOnly,
292
+ "integration.chat.post": leadOnly,
293
+ "integration.chat.read": leadOnly,
294
+ "integration.chat.dm": leadOnly,
289
295
  "integration.slack.post": leadOnly,
290
296
  "integration.slack.read": leadOnly,
291
297
  "integration.slack.thread.start": leadOnly,
@@ -79,6 +79,11 @@ export const PERMISSIONS = {
79
79
  description: "Mutate a task's filesystem artifacts and attachments.",
80
80
  namespace: "task",
81
81
  },
82
+ "task.parent.attach": {
83
+ description:
84
+ "Create a task under an existing parent task. The child inherits the parent's thread context (contextKey, Slack thread, requester).",
85
+ namespace: "task",
86
+ },
82
87
  "task.progress.write": {
83
88
  description:
84
89
  "Write a task's progress, status, or output (its assignee, a lead, a human, or anyone while unassigned).",
@@ -124,6 +129,22 @@ export const PERMISSIONS = {
124
129
  description: "Register or unregister a Kapso inbound number.",
125
130
  namespace: "integration",
126
131
  },
132
+ "integration.chat.manage": {
133
+ description: "Register or unregister a Chat SDK channel route.",
134
+ namespace: "integration",
135
+ },
136
+ "integration.chat.post": {
137
+ description: "Post to a Chat SDK thread or channel other than the thread of the current task.",
138
+ namespace: "integration",
139
+ },
140
+ "integration.chat.read": {
141
+ description: "Read a Chat SDK thread other than the thread of the current task.",
142
+ namespace: "integration",
143
+ },
144
+ "integration.chat.dm": {
145
+ description: "Open a direct-message thread with a user on a Chat SDK adapter.",
146
+ namespace: "integration",
147
+ },
127
148
  "integration.slack.post": {
128
149
  description: "Post to a direct Slack channel.",
129
150
  namespace: "integration",
@@ -23,7 +23,7 @@ import {
23
23
  getScriptApiConnectionDescriptors,
24
24
  getScriptMcpConnectionDescriptors,
25
25
  } from "@/be/script-connections";
26
- import { buildScriptCredentialBindings } from "@/be/script-credential-broker";
26
+ import { buildScriptCredentialBindingsWithFailures } from "@/be/script-credential-broker";
27
27
  import { getScript } from "@/be/scripts/db";
28
28
  import { runScript } from "@/scripts-runtime/loader";
29
29
  import { telemetry } from "@/telemetry";
@@ -99,12 +99,14 @@ async function executeScheduleScript(schedule: ScheduledTask): Promise<void> {
99
99
 
100
100
  let output: Awaited<ReturnType<typeof runScript>>;
101
101
  try {
102
+ const credentials = await buildScriptCredentialBindingsWithFailures({ agentId });
102
103
  output = await runScript({
103
104
  source: script.source,
104
105
  args,
105
106
  fsMode: "none",
106
107
  agentId,
107
- egressSecrets: await buildScriptCredentialBindings({ agentId }),
108
+ egressSecrets: credentials.egressSecrets,
109
+ userConfig: credentials.userConfig,
108
110
  apiConnections: getScriptApiConnectionDescriptors({ agentId }),
109
111
  mcpConnections: getScriptMcpConnectionDescriptors({ agentId }),
110
112
  timeoutMs: 60_000,
@@ -5,6 +5,8 @@ import type {
5
5
  ScriptApiParameterDescriptor,
6
6
  ScriptApiRegistryClient,
7
7
  } from "./api-types";
8
+ import { postSwarmJson } from "./mcp-client";
9
+ import type { SwarmConfig } from "./swarm-config";
8
10
 
9
11
  type FetchResponse = Awaited<ReturnType<typeof fetch>>;
10
12
  type TextResponse = {
@@ -219,12 +221,24 @@ async function throwApiResponseError(
219
221
 
220
222
  export function createApiRegistryClient(
221
223
  descriptors: ScriptApiConnectionDescriptor[] = [],
222
- options: { fetch?: typeof fetch } = {},
224
+ options: { fetch?: typeof fetch; swarmConfig?: SwarmConfig } = {},
223
225
  ): ScriptApiRegistryClient {
224
226
  const fetchImpl = options.fetch ?? fetch;
225
227
  const registry: ScriptApiRegistryClient = {};
226
228
  for (const descriptor of descriptors) {
227
229
  const client: ScriptApiRegistryClient[string] = {};
230
+ if (descriptor.kind === "sql") {
231
+ const { slug, connectionId } = descriptor;
232
+ client.query = async (sql, params) => {
233
+ if (!options.swarmConfig) throw new Error(`ctx.api.${slug}.query needs swarm config`);
234
+ const path = `/api/script-connections/${encodeURIComponent(connectionId)}/sql-query`;
235
+ const body = { sql, params };
236
+ const data = await postSwarmJson(options.swarmConfig, path, body, `ctx.api.${slug}.query`);
237
+ return { rows: data.rows, rowCount: data.rowCount, truncated: data.truncated };
238
+ };
239
+ registry[slug] = client;
240
+ continue;
241
+ }
228
242
  if (descriptor.kind === "graphql") {
229
243
  client.graphql = async (query, variables) => {
230
244
  if (typeof query !== "string") {
@@ -49,9 +49,17 @@ export type ScriptGraphqlConnectionDescriptor = {
49
49
  credential: ScriptApiCredentialDescriptor | null;
50
50
  };
51
51
 
52
+ // The DSN never reaches the sandbox: queries go back to the API server by connection id.
53
+ export type ScriptSqlConnectionDescriptor = {
54
+ slug: string;
55
+ kind: "sql";
56
+ connectionId: string;
57
+ };
58
+
52
59
  export type ScriptApiConnectionDescriptor =
53
60
  | ScriptOpenApiConnectionDescriptor
54
- | ScriptGraphqlConnectionDescriptor;
61
+ | ScriptGraphqlConnectionDescriptor
62
+ | ScriptSqlConnectionDescriptor;
55
63
 
56
64
  export type ScriptMcpToolDescriptor = {
57
65
  name: string;
@@ -34,7 +34,7 @@ export function buildCtx({
34
34
  const swarm = Object.assign(createSwarmSdk(swarmConfig), { config: swarmConfig });
35
35
  return {
36
36
  swarm,
37
- api: createApiRegistryClient(apiConnections),
37
+ api: createApiRegistryClient(apiConnections, { swarmConfig }),
38
38
  mcp: createMcpRegistryClient(mcpConnections, swarmConfig),
39
39
  stdlib,
40
40
  logger: console,
@@ -1,5 +1,6 @@
1
1
  import { getApiKey } from "../utils/api-key";
2
- import { scrubObject, scrubSecrets } from "../utils/secret-scrubber";
2
+ import { getMcpBaseUrl } from "../utils/constants";
3
+ import { createValueScrubber, scrubObject, scrubSecrets } from "../utils/secret-scrubber";
3
4
  import type { ScriptApiConnectionDescriptor, ScriptMcpConnectionDescriptor } from "./api-types";
4
5
  import type { FailedCredentialBinding } from "./credential-broker";
5
6
  import { buildEgressSecrets } from "./egress-secrets";
@@ -66,7 +67,7 @@ async function buildConfigPayload(input: RunScriptInput): Promise<SwarmConfigPay
66
67
  apiKey: { value: apiKey, isSecret: true },
67
68
  agentId: { value: input.agentId, isSecret: false },
68
69
  mcpBaseUrl: {
69
- value: input.mcpBaseUrl ?? process.env.MCP_BASE_URL ?? "http://localhost:3013",
70
+ value: input.mcpBaseUrl ?? getMcpBaseUrl(),
70
71
  isSecret: false,
71
72
  },
72
73
  ...(input.runtimeInstanceId
@@ -94,12 +95,21 @@ export async function runScript(input: RunScriptInput): Promise<RunScriptOutput>
94
95
  };
95
96
  }
96
97
 
98
+ // The global scrubber skips values under its length floor, so this run's own
99
+ // secret config is redacted here at any length before the global pass. Built
100
+ // before the import check: its diagnostic quotes source, which can hold a value.
101
+ const runSecrets = createValueScrubber(
102
+ Object.entries(input.userConfig ?? {})
103
+ .filter(([, entry]) => entry.isSecret)
104
+ .map(([key, entry]) => ({ value: entry.value, name: `config:${key}` })),
105
+ );
106
+
97
107
  const imports = validateScriptImports(input.source);
98
108
  if (!imports.ok) {
99
109
  return {
100
110
  result: undefined,
101
111
  stdout: "",
102
- stderr: imports.diagnostic,
112
+ stderr: scrubSecrets(runSecrets.text(imports.diagnostic)),
103
113
  truncated: { stdout: false, stderr: false },
104
114
  durationMs: 0,
105
115
  exitCode: 1,
@@ -133,9 +143,11 @@ export async function runScript(input: RunScriptInput): Promise<RunScriptOutput>
133
143
 
134
144
  return {
135
145
  ...output,
136
- result: scrubObject(output.result),
137
- stdout: scrubSecrets(output.stdout),
138
- stderr: scrubSecrets(output.stderr),
139
- ...(output.runtimeError ? { runtimeError: scrubObject(output.runtimeError) } : {}),
146
+ result: scrubObject(runSecrets.object(output.result)),
147
+ stdout: scrubSecrets(runSecrets.text(output.stdout)),
148
+ stderr: scrubSecrets(runSecrets.text(output.stderr)),
149
+ ...(output.runtimeError
150
+ ? { runtimeError: scrubObject(runSecrets.object(output.runtimeError)) }
151
+ : {}),
140
152
  };
141
153
  }
@@ -48,36 +48,47 @@ function errorMessage(data: unknown): string {
48
48
  return "unknown MCP proxy error";
49
49
  }
50
50
 
51
+ /** POST to the swarm API as the script's agent; throws unless the reply is `{ ok: true }`. */
52
+ export async function postSwarmJson(
53
+ config: SwarmConfig,
54
+ path: string,
55
+ body: unknown,
56
+ label: string,
57
+ ): Promise<Record<string, unknown>> {
58
+ const baseUrl = Redacted.value(config.mcpBaseUrl).replace(/\/$/, "");
59
+ const response = await fetch(`${baseUrl}${path}`, {
60
+ method: "POST",
61
+ headers: headers(config),
62
+ body: JSON.stringify(body),
63
+ });
64
+ const text = await response.text();
65
+ const data = text ? JSON.parse(text) : {};
66
+ if (!response.ok) {
67
+ throw new Error(`${label} failed with ${response.status}: ${errorMessage(data)}`);
68
+ }
69
+ if (!data || typeof data !== "object" || (data as { ok?: unknown }).ok !== true) {
70
+ throw new Error(`${label} failed: ${errorMessage(data)}`);
71
+ }
72
+ return data as Record<string, unknown>;
73
+ }
74
+
51
75
  export function createMcpRegistryClient(
52
76
  descriptors: ScriptMcpConnectionDescriptor[] = [],
53
77
  config: SwarmConfig,
54
78
  ): ScriptMcpRegistryClient {
55
79
  const registry: ScriptMcpRegistryClient = {};
56
- const baseUrl = Redacted.value(config.mcpBaseUrl).replace(/\/$/, "");
57
80
 
58
81
  for (const descriptor of descriptors) {
59
82
  const client: ScriptMcpRegistryClient[string] = {};
60
83
  for (const { tool, methodName: toolMethod } of methodNames(descriptor.tools)) {
61
84
  client[toolMethod] = async (rawArgs = {}) => {
62
- const response = await fetch(
63
- `${baseUrl}/api/script-connections/${encodeURIComponent(descriptor.connectionId)}/mcp-call`,
64
- {
65
- method: "POST",
66
- headers: headers(config),
67
- body: JSON.stringify({ tool: tool.name, arguments: rawArgs ?? {} }),
68
- },
85
+ const data = await postSwarmJson(
86
+ config,
87
+ `/api/script-connections/${encodeURIComponent(descriptor.connectionId)}/mcp-call`,
88
+ { tool: tool.name, arguments: rawArgs ?? {} },
89
+ `ctx.mcp.${descriptor.slug}.${toolMethod}`,
69
90
  );
70
- const text = await response.text();
71
- const data = text ? JSON.parse(text) : {};
72
- if (!response.ok) {
73
- throw new Error(
74
- `ctx.mcp.${descriptor.slug}.${toolMethod} failed with ${response.status}: ${errorMessage(data)}`,
75
- );
76
- }
77
- if (!data || typeof data !== "object" || (data as { ok?: unknown }).ok !== true) {
78
- throw new Error(`ctx.mcp.${descriptor.slug}.${toolMethod} failed: ${errorMessage(data)}`);
79
- }
80
- return (data as { result: unknown }).result;
91
+ return data.result;
81
92
  };
82
93
  }
83
94
  registry[descriptor.slug] = client;
@@ -104,6 +104,14 @@ export const SDK_TOOL_NAME_MAP = {
104
104
  slack_delete: "slack-delete", // external: mutates Slack, destructive
105
105
  slack_update: "slack-update", // external: mutates Slack
106
106
 
107
+ // ── chat sdk ──
108
+ chat_reply: "chat-reply", // external: sends to the task's chat thread
109
+ chat_post: "chat-post", // external: sends to a chat platform
110
+ chat_openDm: "chat-open-dm", // external: opens a platform DM
111
+ chat_readThread: "chat-read-thread",
112
+ chat_registerChannel: "register-chat-channel",
113
+ chat_unregisterChannel: "unregister-chat-channel", // destructive
114
+
107
115
  // ── messaging (internal) ──
108
116
  message_read: "read-messages",
109
117
  message_post: "post-message",
@@ -115,12 +123,6 @@ export const SDK_TOOL_NAME_MAP = {
115
123
  context_history: "context-history",
116
124
  context_diff: "context-diff",
117
125
 
118
- // ── services ──
119
- service_list: "list-services",
120
- service_register: "register-service",
121
- service_unregister: "unregister-service", // destructive
122
- service_updateStatus: "update-service-status",
123
-
124
126
  // ── workflows ──
125
127
  workflow_list: "list-workflows",
126
128
  workflow_get: "get-workflow",
@@ -280,17 +280,6 @@ function bridgeRequestFor(name: string, args: unknown): BridgeRequest | null {
280
280
  return { method: "DELETE", path: `/api/config/${encodeURIComponent(id)}` };
281
281
  }
282
282
 
283
- // ── services ──
284
- case "service_list":
285
- return {
286
- method: "GET",
287
- path: appendQuery("/api/services", {
288
- agentId: body.agentId,
289
- name: body.name,
290
- status: body.status,
291
- }),
292
- };
293
-
294
283
  // ── workflows ──
295
284
  case "workflow_list":
296
285
  return {
@@ -342,6 +342,8 @@ declare module "swarm-sdk" {
342
342
  types?: Array<"public" | "private" | "dm" | "mpim">;
343
343
  limit?: number;
344
344
  }): Promise<unknown>;
345
+ // --- chat sdk ---
346
+ chat_readThread(args: { threadId: string; limit?: number }): Promise<unknown>;
345
347
  // --- messaging ---
346
348
  message_read(args?: {
347
349
  channel?: string;
@@ -351,13 +353,6 @@ declare module "swarm-sdk" {
351
353
  mentionsOnly?: boolean;
352
354
  markAsRead?: boolean;
353
355
  }): Promise<unknown>;
354
- // --- services ---
355
- service_list(args?: {
356
- agentId?: string;
357
- name?: string;
358
- status?: "starting" | "healthy" | "unhealthy" | "stopped";
359
- includeOwn?: boolean;
360
- }): Promise<unknown>;
361
356
  // --- context / profiles ---
362
357
  context_history(args?: {
363
358
  agentId?: string;
@@ -452,6 +447,7 @@ declare module "swarm-sdk" {
452
447
  scope?: "global" | "agent" | "repo";
453
448
  scopeId?: string;
454
449
  isSecret?: boolean;
450
+ exportToEnv?: boolean;
455
451
  }): Promise<unknown>;
456
452
  config_delete(args: { id: string }): Promise<unknown>;
457
453
 
@@ -492,20 +488,36 @@ declare module "swarm-sdk" {
492
488
  slack_delete(args: { channelId: string; messageTs: string }): Promise<unknown>;
493
489
  slack_update(args: { channelId: string; messageTs: string; message: string }): Promise<unknown>;
494
490
 
491
+ // --- write: chat sdk ---
492
+ chat_reply(args: { text: string }): Promise<unknown>;
493
+ chat_post(args: {
494
+ adapter: "telegram" | "slack" | "discord" | "teams";
495
+ threadId?: string;
496
+ channelId?: string;
497
+ text: string;
498
+ }): Promise<unknown>;
499
+ chat_openDm(args: {
500
+ adapter: "telegram" | "slack" | "discord" | "teams";
501
+ userId: string;
502
+ }): Promise<unknown>;
503
+ chat_registerChannel(args: {
504
+ adapter: "telegram" | "slack" | "discord" | "teams";
505
+ channelId: string;
506
+ agentId?: string;
507
+ workflowId?: string;
508
+ name?: string;
509
+ }): Promise<unknown>;
510
+ chat_unregisterChannel(args: {
511
+ adapter: "telegram" | "slack" | "discord" | "teams";
512
+ channelId: string;
513
+ }): Promise<unknown>;
514
+
495
515
  // --- write: messaging (internal) ---
496
516
  message_post(args: { channel?: string; content: string; to?: string }): Promise<unknown>;
497
517
 
498
518
  // --- write: profiles ---
499
519
  profile_update(args: Record<string, unknown>): Promise<unknown>;
500
520
 
501
- // --- write: services ---
502
- service_register(args: Record<string, unknown>): Promise<unknown>;
503
- service_unregister(args: { name: string }): Promise<unknown>;
504
- service_updateStatus(args: {
505
- name: string;
506
- status: "starting" | "healthy" | "unhealthy" | "stopped";
507
- }): Promise<unknown>;
508
-
509
521
  // --- write: schedules ---
510
522
  schedule_create(args: Record<string, unknown>): Promise<unknown>;
511
523
  schedule_update(args: Record<string, unknown>): Promise<unknown>;
@@ -19,6 +19,7 @@ declare module "swarm-extension" {
19
19
  | "linear"
20
20
  | "jira"
21
21
  | "comb"
22
+ | "chat"
22
23
  | undefined;
23
24
  routingReason?:
24
25
  | "skill"
@@ -132,7 +133,8 @@ declare module "swarm-extension" {
132
133
  | "system"
133
134
  | "linear"
134
135
  | "jira"
135
- | "comb";
136
+ | "comb"
137
+ | "chat";
136
138
  tags: string[];
137
139
  priority: number;
138
140
  dependsOn: string[];
@@ -191,6 +193,7 @@ declare module "swarm-extension" {
191
193
  resolvedModel?: string | undefined;
192
194
  modelSource?: string | undefined;
193
195
  modelAlias?: string | undefined;
196
+ resolvedEffort?: "off" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
194
197
  scheduleId?: string | undefined;
195
198
  workflowRunId?: string | null | undefined;
196
199
  workflowRunStepId?: string | null | undefined;
@@ -467,6 +470,43 @@ declare module "swarm-extension" {
467
470
  kind: "broadcast";
468
471
  };
469
472
  }
473
+ /** A Chat SDK message after its thread buffer flushed, before routing. */
474
+ export interface ChatRouteEvent {
475
+ /** Adapter name, such as `telegram` or `slack`. */
476
+ adapter: string;
477
+ channelId: string;
478
+ /** The Chat SDK thread id, prefixed with the adapter name. */
479
+ threadId: string;
480
+ /** The first buffered sender. */
481
+ userId: string;
482
+ userName?: string;
483
+ /** The buffered messages, joined. */
484
+ text: string;
485
+ botMentioned: boolean;
486
+ isDirectMessage: boolean;
487
+ /** Set when earlier swarm tasks exist in this thread. */
488
+ threadContext?: {
489
+ adapter: string;
490
+ threadId: string;
491
+ };
492
+ }
493
+ export interface ChatRouteModify {
494
+ target:
495
+ | {
496
+ kind: "agent";
497
+ agentId: string;
498
+ }
499
+ | {
500
+ kind: "lead";
501
+ }
502
+ | {
503
+ kind: "broadcast";
504
+ }
505
+ | {
506
+ kind: "workflow";
507
+ workflowId: string;
508
+ };
509
+ }
470
510
  export type HeartbeatClassification = "no-session" | "stale-session" | "fresh-stalled";
471
511
  export type HeartbeatAction = "supersede-resume" | "fail" | "record";
472
512
  export interface HeartbeatRemediateEvent {
@@ -511,6 +551,18 @@ declare module "swarm-extension" {
511
551
  threadTs?: string;
512
552
  taskId?: string;
513
553
  }
554
+ /** A Chat SDK message the swarm received or sent. */
555
+ export interface ChatMessageEvent {
556
+ adapter: string;
557
+ channelId: string;
558
+ threadId: string;
559
+ /** The sender, for an inbound message. */
560
+ userId?: string;
561
+ text: string;
562
+ direction: "inbound" | "outbound";
563
+ taskId?: string;
564
+ messageId?: string;
565
+ }
514
566
  /**
515
567
  * A person answered an approval request. Fires for workflow and standalone
516
568
  * requests. Timeouts and cancellations do not emit it today.
@@ -619,6 +671,11 @@ declare module "swarm-extension" {
619
671
  modify: SlackRouteModify;
620
672
  result: PreResult<SlackRouteModify>;
621
673
  };
674
+ "pre.chat.route": {
675
+ event: ChatRouteEvent;
676
+ modify: ChatRouteModify;
677
+ result: PreResult<ChatRouteModify>;
678
+ };
622
679
  "pre.heartbeat.remediate": {
623
680
  event: HeartbeatRemediateEvent;
624
681
  modify: HeartbeatRemediateModify;
@@ -664,6 +721,11 @@ declare module "swarm-extension" {
664
721
  modify: never;
665
722
  result: void;
666
723
  };
724
+ "post.chat.message": {
725
+ event: ChatMessageEvent;
726
+ modify: never;
727
+ result: void;
728
+ };
667
729
  "post.approval.resolved": {
668
730
  event: ApprovalResolvedEvent;
669
731
  modify: never;