@desplega.ai/agent-swarm 1.173.0 → 2.1.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 (511) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-ccm9xrep.js → acp-adapter-kr4abrsk.js} +17 -16
  3. package/dist/{actions-sgeyv08k.js → actions-eh4g6w2r.js} +39 -34
  4. package/dist/{amp-adapter-gpxp3kc9.js → amp-adapter-7h7wdt8q.js} +8 -7
  5. package/dist/{app-km9qnv2f.js → app-7k8s9w5p.js} +18 -14
  6. package/dist/{assistant-5r8tcvvd.js → assistant-wswt2y7p.js} +40 -35
  7. package/dist/{boot-reembed-16rv9843.js → boot-reembed-9apm9qw6.js} +10 -9
  8. package/dist/{boot-reembed-swwzdgd7.js → boot-reembed-whzbdthj.js} +10 -9
  9. package/dist/{boot-scrub-sweep-zkr6vkqb.js → boot-scrub-sweep-ndzmvmgt.js} +11 -10
  10. package/dist/{boot-seeds-d8sp49t2.js → boot-seeds-e9sta0yt.js} +16 -13
  11. package/dist/{claude-adapter-yzzzh8jp.js → claude-adapter-4mqd3r6r.js} +19 -18
  12. package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-9wswb52m.js} +7 -5
  13. package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-tpe1effx.js} +6 -4
  14. package/dist/{claude-sdk-session-4whxere4.js → claude-sdk-session-q49ghmh9.js} +12402 -11850
  15. package/dist/{cli-ne7smj1b.js → cli-01xvj1rq.js} +10 -10
  16. package/dist/{cli-nwrdx840.js → cli-035vekcw.js} +3 -3
  17. package/dist/{cli-9xf7fdtp.js → cli-0pd8hzhc.js} +29 -6
  18. package/dist/{cli-tmhsxhb8.js → cli-0veb92a3.js} +28 -6
  19. package/dist/{cli-c3rk1v0x.js → cli-10jesr25.js} +3 -3
  20. package/dist/{cli-6thk4jz3.js → cli-1y7yywmj.js} +6 -6
  21. package/dist/{cli-6r2f7edk.js → cli-20krdhz5.js} +47 -19
  22. package/dist/{cli-rfs4vddv.js → cli-29rja109.js} +39 -20
  23. package/dist/cli-2m1ktfzz.js +17795 -0
  24. package/dist/{cli-na2pxe4f.js → cli-2pwa0q4d.js} +15 -4
  25. package/dist/{cli-7a93cv8c.js → cli-4mengw46.js} +441 -43
  26. package/dist/{cli-94b48jhk.js → cli-5twdke5x.js} +16 -14
  27. package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
  28. package/dist/cli-6cvfxs8r.js +47 -0
  29. package/dist/{cli-w1apjecb.js → cli-711vwbxn.js} +2 -2
  30. package/dist/{cli-r4fqfpwf.js → cli-78vv7446.js} +50 -27
  31. package/dist/{cli-srqq3gc5.js → cli-7n6s5man.js} +5 -5
  32. package/dist/{cli-m89t9jdf.js → cli-7x0g4sn1.js} +15416 -16024
  33. package/dist/{cli-2bw3w47j.js → cli-8wwxw8a3.js} +1 -1
  34. package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
  35. package/dist/{cli-ywm1azg9.js → cli-9jzdj90z.js} +8 -4
  36. package/dist/cli-9traj3dn.js +638 -0
  37. package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
  38. package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
  39. package/dist/cli-cvv9k0hh.js +10143 -0
  40. package/dist/{cli-anzdk0z4.js → cli-d9286m9h.js} +2 -2
  41. package/dist/cli-e3g5mbkz.js +776 -0
  42. package/dist/cli-f527ce74.js +781 -0
  43. package/dist/{cli-gmdajfw5.js → cli-gxzkg1de.js} +5020 -1729
  44. package/dist/{cli-451ks6aw.js → cli-h1arqn31.js} +1 -1
  45. package/dist/cli-hjwmhcg1.js +10622 -0
  46. package/dist/{cli-jpc4r224.js → cli-hqr88ew6.js} +19 -3
  47. package/dist/{cli-h7k0xtry.js → cli-hvqbtna4.js} +4 -1256
  48. package/dist/{cli-cd0hv9nh.js → cli-j67mh2vg.js} +2 -2
  49. package/dist/cli-jta2eyzc.js +619 -0
  50. package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
  51. package/dist/cli-kceah1eh.js +92 -0
  52. package/dist/{cli-d603qf86.js → cli-ksphgh48.js} +10 -8
  53. package/dist/{cli-3nxdmjrc.js → cli-mgz4nbgg.js} +4 -4
  54. package/dist/{cli-saqyage0.js → cli-mz5as5ha.js} +179 -27
  55. package/dist/cli-n2wq4j7m.js +6985 -0
  56. package/dist/{cli-ppy4nnnh.js → cli-n8ndw8j7.js} +2 -2
  57. package/dist/{cli-1w0vj3gw.js → cli-naqzr17j.js} +7 -7
  58. package/dist/{cli-0a7mm3zp.js → cli-nm1p8jfr.js} +25 -21
  59. package/dist/{cli-wrh08zjd.js → cli-p3zbc1rw.js} +5 -18
  60. package/dist/{cli-hsem16hb.js → cli-pe05f8yk.js} +29 -6
  61. package/dist/{cli-5wpw4rab.js → cli-qmzsbkvy.js} +5 -5
  62. package/dist/{cli-bv2etw2y.js → cli-qnm4e9e4.js} +99 -590
  63. package/dist/{cli-1x7da0de.js → cli-qqy4q48b.js} +8 -8
  64. package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
  65. package/dist/{cli-5er5gjbm.js → cli-r35rw5de.js} +15 -15
  66. package/dist/{cli-v3zhnxsb.js → cli-r610p9bs.js} +2 -2
  67. package/dist/{cli-7jykv7ef.js → cli-rc6pf5kv.js} +1 -1
  68. package/dist/{cli-x119kdba.js → cli-rdxm77k3.js} +1 -1
  69. package/dist/cli-rhs9pz33.js +294 -0
  70. package/dist/{cli-0p3enk35.js → cli-s69nfyeh.js} +9 -1
  71. package/dist/{cli-0kxf81jj.js → cli-sawv63e8.js} +2 -2
  72. package/dist/{cli-e3pmyt39.js → cli-sg19gbf0.js} +1 -1
  73. package/dist/{cli-d161g69q.js → cli-shk7r5cs.js} +57 -6
  74. package/dist/{cli-7pz3b7x5.js → cli-sksetb2q.js} +36 -1
  75. package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
  76. package/dist/{cli-db3m6zdt.js → cli-t02z59f2.js} +1 -1
  77. package/dist/{cli-b07hr3bt.js → cli-txqb9s38.js} +2 -2
  78. package/dist/{cli-s8z6x4b4.js → cli-v7g551te.js} +225 -113
  79. package/dist/{cli-rfz2ve55.js → cli-vgqzp4em.js} +3341 -955
  80. package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
  81. package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
  82. package/dist/cli-wfnemr1t.js +86 -0
  83. package/dist/cli-wmgrkscj.js +23254 -0
  84. package/dist/{cli-qm1448f9.js → cli-wms6x9db.js} +8 -8
  85. package/dist/{cli-tadfgd0t.js → cli-x1r545x8.js} +33 -4
  86. package/dist/{cli-xc7p7s3g.js → cli-xczsgshn.js} +6 -6
  87. package/dist/{cli-fmhj1ehj.js → cli-y3167wt1.js} +882 -271
  88. package/dist/{cli-r0byd61h.js → cli-yjmqpxt3.js} +17 -16
  89. package/dist/{cli-81r1wjyv.js → cli-z780ec7c.js} +1 -1
  90. package/dist/{cli-phcqp1b9.js → cli-zm9t2vde.js} +2 -2
  91. package/dist/cli.js +34 -49
  92. package/dist/{codex-adapter-r3dn4fp5.js → codex-adapter-4z16v9n0.js} +15 -14
  93. package/dist/{codex-login-841kv5fk.js → codex-login-pkepy2j1.js} +3 -2
  94. package/dist/{codex-session-runner-fwt793h4.js → codex-session-runner-rvms9y2x.js} +15 -14
  95. package/dist/{commands-z8fq9qna.js → commands-2a9rtyat.js} +11 -10
  96. package/dist/{controller-hq5ggpcp.js → controller-3k3madbn.js} +5 -4
  97. package/dist/{controllers-connect-3mf2btyj.js → controllers-connect-v9yn8zb9.js} +42 -37
  98. package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-98gbhyzn.js} +7 -6
  99. package/dist/{db-qfpq4bt7.js → db-eywwsnjw.js} +30 -9
  100. package/dist/{db-yyhqqrbf.js → db-ncypk9np.js} +12 -11
  101. package/dist/{devin-adapter-xgtj680j.js → devin-adapter-zeq8b9gz.js} +3 -2
  102. package/dist/{dispatcher-x0x7qfcq.js → dispatcher-w94kc575.js} +38 -33
  103. package/dist/{docker-f503k9p0.js → docker-b1e4cqab.js} +3 -2
  104. package/dist/{dsh-adapter-34etvb5m.js → dsh-adapter-47ztej36.js} +7 -6
  105. package/dist/{e2b-66xra4az.js → e2b-bbt8ey45.js} +4 -3
  106. package/dist/{e2b-xwhyj8cw.js → e2b-dp804sen.js} +4 -3
  107. package/dist/{event-bus-vjtv82gm.js → event-bus-j2jdg3qb.js} +3 -2
  108. package/dist/{external-channel-h1fjecwe.js → external-channel-zrkg8ar9.js} +11 -10
  109. package/dist/{google-generative-ai-szdxbpqg.js → google-generative-ai-g8db7x0f.js} +4 -2
  110. package/dist/{google-vertex-qzw3p36d.js → google-vertex-r2692q0r.js} +4 -2
  111. package/dist/{grok-adapter-e7mr287e.js → grok-adapter-s9ncp9vy.js} +18 -17
  112. package/dist/{handlers-znb9n7d4.js → handlers-kqftvjgw.js} +41 -36
  113. package/dist/{heartbeat-bm4qkn8d.js → heartbeat-9q96p8v9.js} +43 -38
  114. package/dist/{hook-254r4mza.js → hook-56qe10dp.js} +11 -23
  115. package/dist/{hook-xaa3q80s.js → hook-yy6rw42k.js} +12 -11
  116. package/dist/{http-3dgrgp8y.js → http-r2dnb8f8.js} +2411 -275
  117. package/dist/{index-fx3jqq1e.js → index-3gtmkhc6.js} +38 -33
  118. package/dist/{index-bdsqa799.js → index-3k5hkz7r.js} +43 -38
  119. package/dist/index-52j1aja4.js +3465 -0
  120. package/dist/{index-g2byveez.js → index-5e101240.js} +38 -33
  121. package/dist/{index-2ybk7khy.js → index-5wyfjc2c.js} +845 -683
  122. package/dist/index-9gw58n4k.js +193 -0
  123. package/dist/index-9j87mcm8.js +56305 -0
  124. package/dist/index-bsmcresk.js +79424 -0
  125. package/dist/index-mh85qhec.js +475 -0
  126. package/dist/{index-jd7sejm2.js → index-vxvhxxbn.js} +10 -9
  127. package/dist/index-we27kd31.js +12810 -0
  128. package/dist/{keepalive-6ywhpja1.js → keepalive-psj6j54c.js} +12 -11
  129. package/dist/{lead-cw45n21s.js → lead-hajz4688.js} +61 -56
  130. package/dist/{maintenance-ss1a1ge9.js → maintenance-ps02sb5m.js} +10 -9
  131. package/dist/{node-fkajaq96.js → node-mwb5r697.js} +2 -1
  132. package/dist/{oauth-refresh-sweep-3c6f8vyy.js → oauth-refresh-sweep-0284h93b.js} +11 -10
  133. package/dist/{onboard-8hzdhc1k.js → onboard-rbf6bg01.js} +11 -3
  134. package/dist/{opencode-adapter-qbchbcfz.js → opencode-adapter-13dcatgq.js} +18 -13
  135. package/dist/{otel-impl-e6mnvc4v.js → otel-impl-zvqcbhp7.js} +242 -868
  136. package/dist/{pi-mono-adapter-3c9g9snh.js → pi-mono-adapter-xxy47q4v.js} +244 -106
  137. package/dist/{pricing-refresh-gedkjdw0.js → pricing-refresh-kefx9v3t.js} +12 -11
  138. package/dist/{rbac-roles-dt4vh1yy.js → rbac-roles-3m36rxm2.js} +11 -10
  139. package/dist/{rbac-roles-eszdg6pm.js → rbac-roles-z76xv0hq.js} +12 -11
  140. package/dist/{render-v2-907cy6sa.js → render-v2-wz73bs25.js} +18 -14
  141. package/dist/{resume-42stcaz0.js → resume-k4wzge8w.js} +25 -21
  142. package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
  143. package/dist/{setup-adbc1c10.js → setup-2fp2pypp.js} +2 -2
  144. package/dist/{virtual-modules-rtmt494q.js → virtual-modules-9gkxqrap.js} +6 -5
  145. package/dist/{work-objects-wpj8ck95.js → work-objects-6k0ywz3m.js} +41 -36
  146. package/dist/{worker-bzdra9rf.js → worker-5v3rxsdh.js} +61 -56
  147. package/dist/{x-qfmygqqv.js → x-4mtdeym1.js} +3 -2
  148. package/openapi.json +1279 -329
  149. package/package.json +15 -15
  150. package/src/agentmail/handlers.ts +21 -11
  151. package/src/apps/definition.ts +16 -0
  152. package/src/azure-devops/api.ts +52 -2
  153. package/src/azure-devops/boards-sync.ts +50 -20
  154. package/src/azure-devops/index.ts +1 -0
  155. package/src/azure-devops/outbound.ts +95 -0
  156. package/src/be/boot-seeds.ts +11 -0
  157. package/src/be/config-refs.ts +60 -0
  158. package/src/be/db/model-profiles.ts +315 -0
  159. package/src/be/db/page-versions.ts +15 -0
  160. package/src/be/db/runtime.ts +35 -8
  161. package/src/be/db/skill-name-resolution.ts +36 -0
  162. package/src/be/db/tasks/read.ts +237 -0
  163. package/src/be/db/tasks/write.ts +7 -0
  164. package/src/be/db.ts +87 -36
  165. package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
  166. package/src/be/migrations/216_task_resolved_effort.sql +5 -0
  167. package/src/be/migrations/217_chat_sdk_state.sql +104 -0
  168. package/src/be/migrations/219_relabel_pi_context_compactions.sql +22 -0
  169. package/src/be/migrations/220_model_profiles.sql +137 -0
  170. package/src/be/model-catalog-store.ts +5 -1
  171. package/src/be/model-tier-resolution.ts +155 -10
  172. package/src/be/model-validation.ts +12 -2
  173. package/src/be/models-catalog.ts +26 -1
  174. package/src/be/modelsdev-cache.json +198 -63
  175. package/src/be/modelsdev-cache.ts +9 -1
  176. package/src/be/script-credential-broker.ts +39 -2
  177. package/src/be/scripts/run-saved.ts +1 -0
  178. package/src/be/scripts/typecheck.ts +22 -8
  179. package/src/be/secret-registry.ts +6 -2
  180. package/src/be/seed/runner.ts +13 -1
  181. package/src/be/seed/state-db.ts +5 -0
  182. package/src/be/seed/types.ts +6 -0
  183. package/src/be/seed-model-profiles.ts +41 -0
  184. package/src/be/seed-pricing.ts +19 -2
  185. package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +368 -0
  186. package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
  187. package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
  188. package/src/be/seed-scripts/index.ts +9 -0
  189. package/src/be/seed-skills/bundled-files.generated.json +0 -18
  190. package/src/be/seed-skills/index.ts +104 -3
  191. package/src/be/swarm-config-guard.ts +53 -0
  192. package/src/cli.tsx +0 -16
  193. package/src/commands/onboard/non-interactive.ts +4 -2
  194. package/src/commands/provider-credentials.ts +52 -6
  195. package/src/commands/runner.ts +193 -71
  196. package/src/e2b/env.ts +5 -0
  197. package/src/extensions/catalog.generated.json +17 -0
  198. package/src/extensions/contract-types.generated.ts +1 -1
  199. package/src/extensions/contract.ts +45 -0
  200. package/src/extensions/dispatcher.ts +7 -0
  201. package/src/extensions/loader.ts +10 -5
  202. package/src/extensions/post-bridge.ts +40 -0
  203. package/src/github/handlers.ts +11 -4
  204. package/src/heartbeat/heartbeat.ts +2 -1
  205. package/src/heartbeat/templates.ts +8 -5
  206. package/src/hooks/hook.ts +0 -26
  207. package/src/http/agents.ts +49 -2
  208. package/src/http/all-routes.ts +1 -1
  209. package/src/http/apps.ts +30 -3
  210. package/src/http/config.ts +62 -19
  211. package/src/http/core.ts +8 -0
  212. package/src/http/index.ts +25 -3
  213. package/src/http/integrations.ts +88 -1
  214. package/src/http/mcp.ts +15 -5
  215. package/src/http/model-profiles.ts +303 -0
  216. package/src/http/page-proxy.ts +2 -4
  217. package/src/http/pages-public.ts +13 -7
  218. package/src/http/pages.ts +3 -13
  219. package/src/http/poll.ts +42 -71
  220. package/src/http/requested-by.ts +54 -0
  221. package/src/http/script-runs.ts +1 -1
  222. package/src/http/scripts.ts +26 -2
  223. package/src/http/stats.ts +1 -30
  224. package/src/http/tasks.ts +79 -5
  225. package/src/http/utils.ts +14 -0
  226. package/src/http/webhooks.ts +160 -3
  227. package/src/http/x.ts +1 -0
  228. package/src/integrations/chat-sdk/adapters.ts +129 -0
  229. package/src/integrations/chat-sdk/attachments.ts +232 -0
  230. package/src/integrations/chat-sdk/background.ts +36 -0
  231. package/src/integrations/chat-sdk/commands.ts +194 -0
  232. package/src/integrations/chat-sdk/config.ts +198 -0
  233. package/src/integrations/chat-sdk/discord-api.ts +63 -0
  234. package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
  235. package/src/integrations/chat-sdk/handlers.ts +28 -0
  236. package/src/integrations/chat-sdk/inbound.ts +426 -0
  237. package/src/integrations/chat-sdk/limits.ts +48 -0
  238. package/src/integrations/chat-sdk/logger.ts +81 -0
  239. package/src/integrations/chat-sdk/outbound.ts +123 -0
  240. package/src/integrations/chat-sdk/relay.ts +172 -0
  241. package/src/integrations/chat-sdk/router.ts +169 -0
  242. package/src/integrations/chat-sdk/runtime.ts +351 -0
  243. package/src/integrations/chat-sdk/schema.ts +245 -0
  244. package/src/integrations/chat-sdk/state.ts +243 -0
  245. package/src/integrations/chat-sdk/status.ts +244 -0
  246. package/src/integrations/chat-sdk/steering.ts +58 -0
  247. package/src/integrations/chat-sdk/teams-origin.ts +77 -0
  248. package/src/integrations/chat-sdk/telegram-api.ts +56 -0
  249. package/src/integrations/chat-sdk/templates.ts +16 -0
  250. package/src/integrations/chat-sdk/test-hooks.ts +37 -0
  251. package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
  252. package/src/integrations/chat-sdk/typing.ts +65 -0
  253. package/src/{artifact-sdk → pages}/feedback-overlay.ts +65 -6
  254. package/src/pages/version.ts +4 -5
  255. package/src/prompts/base-prompt.ts +111 -45
  256. package/src/providers/acp-target-catalog.ts +6 -0
  257. package/src/providers/acp-targets.ts +56 -3
  258. package/src/providers/amp-adapter.ts +1 -1
  259. package/src/providers/claude-adapter.ts +1 -1
  260. package/src/providers/claude-flag-settings.ts +17 -5
  261. package/src/providers/claude-managed-adapter.ts +1 -1
  262. package/src/providers/claude-session-events.ts +6 -1
  263. package/src/providers/dsh-adapter.ts +1 -1
  264. package/src/providers/opencode-adapter.ts +243 -26
  265. package/src/providers/opencode-swarm-plugin.ts +31 -0
  266. package/src/providers/pi-mono-adapter.ts +398 -153
  267. package/src/providers/pi-mono-extension.ts +17 -3
  268. package/src/providers/pricing-sources.md +33 -2
  269. package/src/providers/reasoning-effort.ts +37 -0
  270. package/src/providers/types.ts +6 -2
  271. package/src/rbac/legacy-policy.ts +16 -2
  272. package/src/rbac/permissions.ts +26 -0
  273. package/src/scheduler/deferred-task-waits.ts +18 -5
  274. package/src/scheduler/scheduler.ts +11 -3
  275. package/src/scripts-runtime/executors/quickjs-prelude.ts +75 -6
  276. package/src/scripts-runtime/executors/quickjs-runner.ts +85 -8
  277. package/src/scripts-runtime/executors/quickjs-web-shims.ts +1041 -0
  278. package/src/scripts-runtime/extract-args-schema.ts +9 -8
  279. package/src/scripts-runtime/loader.ts +19 -7
  280. package/src/scripts-runtime/quickjs-compat.ts +464 -0
  281. package/src/scripts-runtime/sdk-allowlist.ts +12 -6
  282. package/src/scripts-runtime/swarm-sdk.ts +0 -11
  283. package/src/scripts-runtime/types/stdlib.d.ts +39 -15
  284. package/src/scripts-runtime/types/swarm-extension.d.ts +66 -1
  285. package/src/scripts-runtime/types/swarm-sdk.d.ts +39 -15
  286. package/src/server.ts +62 -19
  287. package/src/slack/blocks.ts +4 -2
  288. package/src/slack/event-dedup.ts +1 -1
  289. package/src/slack/reaction-shortcode.ts +14 -0
  290. package/src/slack/render-v2.ts +12 -7
  291. package/src/slack/responses.ts +5 -4
  292. package/src/slack/thread-buffer.ts +41 -22
  293. package/src/tasks/additive-buffer.ts +4 -2
  294. package/src/tasks/context-key.ts +60 -1
  295. package/src/tasks/model-pin.ts +67 -0
  296. package/src/tasks/worker-follow-up.ts +15 -33
  297. package/src/tests/acp-adapter.test.ts +42 -0
  298. package/src/tests/agentmail-filters.test.ts +47 -0
  299. package/src/tests/api-drain-worker-e2e.test.ts +1 -6
  300. package/src/tests/apps-spike2.test.ts +35 -0
  301. package/src/tests/azure-devops-outbound.test.ts +420 -0
  302. package/src/tests/base-prompt.test.ts +58 -54
  303. package/src/tests/chat-sdk-commands.test.ts +191 -0
  304. package/src/tests/chat-sdk-config.test.ts +334 -0
  305. package/src/tests/chat-sdk-discord-api.test.ts +68 -0
  306. package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
  307. package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
  308. package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
  309. package/src/tests/chat-sdk-harness.ts +146 -0
  310. package/src/tests/chat-sdk-inbound.test.ts +363 -0
  311. package/src/tests/chat-sdk-relay.test.ts +470 -0
  312. package/src/tests/chat-sdk-reload.test.ts +128 -0
  313. package/src/tests/chat-sdk-shutdown.test.ts +220 -0
  314. package/src/tests/chat-sdk-slack.test.ts +268 -0
  315. package/src/tests/chat-sdk-state.test.ts +163 -0
  316. package/src/tests/chat-sdk-status-route.test.ts +382 -0
  317. package/src/tests/chat-sdk-teams.test.ts +277 -0
  318. package/src/tests/chat-sdk-tools.test.ts +520 -0
  319. package/src/tests/chat-sdk-typing.test.ts +120 -0
  320. package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
  321. package/src/tests/claude-adapter-binary.test.ts +9 -4
  322. package/src/tests/claude-flag-settings.test.ts +11 -3
  323. package/src/tests/claude-managed-adapter.test.ts +1 -1
  324. package/src/tests/claude-sdk-lifecycle.test.ts +9 -3
  325. package/src/tests/claude-thinking-tokens.test.ts +57 -0
  326. package/src/tests/claude-worker-parity.test.ts +2 -7
  327. package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
  328. package/src/tests/config-refs.test.ts +66 -0
  329. package/src/tests/context-key.test.ts +19 -0
  330. package/src/tests/cors-allowlist.test.ts +25 -0
  331. package/src/tests/create-page-tool.test.ts +18 -0
  332. package/src/tests/credential-check.test.ts +139 -0
  333. package/src/tests/credentials.test.ts +21 -0
  334. package/src/tests/db-runtime.test.ts +61 -0
  335. package/src/tests/db-task-read-contract.test.ts +22 -0
  336. package/src/tests/db-task-write-contract.test.ts +11 -0
  337. package/src/tests/deferred-task-wake.test.ts +78 -1
  338. package/src/tests/docs-index-footprint.test.js +3 -3
  339. package/src/tests/dsh-adapter.test.ts +1 -1
  340. package/src/tests/enabled-capabilities.test.ts +20 -0
  341. package/src/tests/entrypoint-api-readiness.test.ts +14 -8
  342. package/src/tests/entrypoint-config-env-export.test.ts +5 -2
  343. package/src/tests/entrypoint-export-to-env.test.ts +78 -0
  344. package/src/tests/env-flag.test.ts +1 -0
  345. package/src/tests/explicit-model-validation.test.ts +105 -1
  346. package/src/tests/extensions-catalog.test.ts +1 -0
  347. package/src/tests/extensions-example-comms-adherence-gate.test.ts +413 -0
  348. package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
  349. package/src/tests/extensions-loader.test.ts +15 -0
  350. package/src/tests/extensions-post-bridge.test.ts +51 -0
  351. package/src/tests/fetch-resolved-env.test.ts +128 -0
  352. package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
  353. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
  354. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
  355. package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
  356. package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
  357. package/src/tests/github-handlers.test.ts +35 -0
  358. package/src/tests/harness-provider-resolution.test.ts +12 -0
  359. package/src/tests/heartbeat-checklist.test.ts +3 -2
  360. package/src/tests/heartbeat-jev-gate-credentials.test.ts +168 -0
  361. package/src/tests/heartbeat-jev-gate.test.ts +385 -0
  362. package/src/tests/hook-runtime-close.test.ts +0 -2
  363. package/src/tests/http-api-integration.test.ts +0 -25
  364. package/src/tests/migration-046-budgets.test.ts +17 -16
  365. package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
  366. package/src/tests/model-profile-backcompat.test.ts +327 -0
  367. package/src/tests/model-profile-providers.test.ts +302 -0
  368. package/src/tests/model-profile-runtime-secrets.test.ts +223 -0
  369. package/src/tests/model-profiles-api.test.ts +614 -0
  370. package/src/tests/model-tier-resolution.test.ts +93 -0
  371. package/src/tests/models-catalog.test.ts +42 -1
  372. package/src/tests/openai-compatible-providers.test.ts +134 -0
  373. package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
  374. package/src/tests/opencode-adapter.test.ts +216 -2
  375. package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
  376. package/src/tests/opencode-shell-env.test.ts +145 -0
  377. package/src/tests/openrouter-base-url.test.ts +101 -151
  378. package/src/tests/page-proxy.test.ts +1 -1
  379. package/src/tests/pages-browser-sdk.test.ts +76 -0
  380. package/src/tests/pages-feedback-keys.test.ts +121 -0
  381. package/src/tests/pages-feedback.test.ts +4 -1
  382. package/src/tests/paused-tasks-requested-by.test.ts +102 -0
  383. package/src/tests/pi-context-compaction.test.ts +193 -0
  384. package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
  385. package/src/tests/pi-mono-adapter.test.ts +385 -5
  386. package/src/tests/pi-shell-env.test.ts +170 -0
  387. package/src/tests/profile-claim.test.ts +269 -0
  388. package/src/tests/prompt-template-remaining.test.ts +35 -0
  389. package/src/tests/quickjs-compat.test.ts +213 -0
  390. package/src/tests/rbac-engine.test.ts +32 -3
  391. package/src/tests/runner-exit-after-tasks.test.ts +0 -4
  392. package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
  393. package/src/tests/script-connections.test.ts +6 -0
  394. package/src/tests/script-executor-conformance.test.ts +252 -1
  395. package/src/tests/script-executor-quickjs.test.ts +96 -0
  396. package/src/tests/script-runs-http.test.ts +89 -0
  397. package/src/tests/scripts-http.test.ts +217 -1
  398. package/src/tests/scripts-only-gating.test.ts +2 -3
  399. package/src/tests/scripts-runtime.test.ts +58 -40
  400. package/src/tests/secret-scrubber.test.ts +96 -0
  401. package/src/tests/seed-model-profiles.test.ts +174 -0
  402. package/src/tests/seed-scripts.test.ts +2 -2
  403. package/src/tests/seed-skills-bundled-files.test.ts +45 -53
  404. package/src/tests/seed-skills-retire.test.ts +182 -0
  405. package/src/tests/send-task-requester-gate.test.ts +58 -0
  406. package/src/tests/session-cost-recompute-unit.test.ts +46 -0
  407. package/src/tests/skill-get-name-resolution.test.ts +137 -0
  408. package/src/tests/skill-invocations.test.ts +4 -2
  409. package/src/tests/slack-blocks.test.ts +36 -0
  410. package/src/tests/slack-inline-output.test.ts +14 -0
  411. package/src/tests/slack-reaction-config.test.ts +20 -0
  412. package/src/tests/slack-render-v2.test.ts +37 -0
  413. package/src/tests/slack-thread-buffer.test.ts +98 -1
  414. package/src/tests/sonnet-5-5-registry.test.ts +9 -1
  415. package/src/tests/swarm-config-export-to-env.test.ts +267 -0
  416. package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
  417. package/src/tests/swarm-diff.test.ts +1 -1
  418. package/src/tests/task-model-effort-rerun.test.ts +164 -0
  419. package/src/tests/task-session-prompts.test.ts +132 -0
  420. package/src/tests/task-tool-manifest.test.ts +14 -0
  421. package/src/tests/task-tools-ctx.test.ts +2 -0
  422. package/src/tests/tool-annotations.test.ts +6 -6
  423. package/src/tests/ui-logs-parser.test.ts +43 -0
  424. package/src/tests/used-by-route.test.ts +6 -0
  425. package/src/tests/vercel-ai-gateway.test.ts +149 -0
  426. package/src/tests/workflow-llm.test.ts +61 -0
  427. package/src/tests/workflow-swarm-script.test.ts +38 -0
  428. package/src/tests/workflow-wait-filter.test.ts +5 -3
  429. package/src/tools/chat-access.ts +41 -0
  430. package/src/tools/chat-open-dm.ts +59 -0
  431. package/src/tools/chat-post.ts +74 -0
  432. package/src/tools/chat-read-thread.ts +100 -0
  433. package/src/tools/chat-reply.ts +75 -0
  434. package/src/tools/create-page.ts +3 -13
  435. package/src/tools/model-catalog/index.ts +2 -1
  436. package/src/tools/model-profiles/list-model-profiles.ts +54 -0
  437. package/src/tools/register-chat-channel.ts +139 -0
  438. package/src/tools/request-human-input.ts +11 -3
  439. package/src/tools/script-apis.ts +5 -1
  440. package/src/tools/script-upsert.ts +4 -1
  441. package/src/tools/send-task.ts +48 -1
  442. package/src/tools/skills/skill-get.ts +17 -9
  443. package/src/tools/swarm-config/get-config.ts +2 -1
  444. package/src/tools/swarm-config/list-config.ts +2 -1
  445. package/src/tools/swarm-config/set-config.ts +16 -3
  446. package/src/tools/system-one-decide.ts +104 -0
  447. package/src/tools/task-action.ts +22 -1
  448. package/src/tools/tool-config.ts +14 -6
  449. package/src/types.ts +48 -3
  450. package/src/utils/config-env-export.ts +74 -0
  451. package/src/utils/credentials.test.ts +92 -0
  452. package/src/utils/credentials.ts +52 -4
  453. package/src/utils/harness-provider.ts +15 -6
  454. package/src/utils/runtime-model-catalog.ts +11 -1
  455. package/src/utils/secret-scrubber.ts +86 -10
  456. package/src/utils/task-tool-manifest.ts +19 -2
  457. package/src/utils/vcs-repo-match.ts +29 -0
  458. package/src/workflows/executors/raw-llm.ts +8 -3
  459. package/src/workflows/executors/swarm-script.ts +1 -0
  460. package/src/workflows/executors/system-one-decision.ts +21 -11
  461. package/src/workflows/executors/workflow-llm.ts +22 -0
  462. package/src/workflows/index.ts +21 -12
  463. package/templates/extensions/README.md +1 -0
  464. package/templates/extensions/comms-adherence-gate/README.md +88 -0
  465. package/templates/extensions/comms-adherence-gate/hooks.ts +489 -0
  466. package/templates/extensions/comms-adherence-gate/manifest.json +8 -0
  467. package/templates/skills/agent-browser/SKILL.md +1 -1
  468. package/templates/skills/agent-browser/content.md +1 -1
  469. package/templates/skills/apps/SKILL.md +8 -1
  470. package/templates/skills/apps/content.md +8 -1
  471. package/templates/skills/chat-sdk/config.json +14 -0
  472. package/templates/skills/chat-sdk/content.md +84 -0
  473. package/templates/skills/composio-gmail/content.md +7 -0
  474. package/templates/skills/composio-google-docs/content.md +1 -1
  475. package/templates/skills/email-domain-health/config.json +14 -0
  476. package/templates/skills/email-domain-health/content.md +131 -0
  477. package/templates/skills/kv-storage/content.md +2 -2
  478. package/templates/skills/pages/content.md +8 -10
  479. package/templates/skills/swarm-extensions/content.md +2 -0
  480. package/templates/skills/swarm-scripts/SKILL.md +4 -2
  481. package/templates/skills/swarm-scripts/config.json +1 -1
  482. package/templates/skills/swarm-scripts/content.md +4 -2
  483. package/templates/skills/workflow-iterate/content.md +38 -0
  484. package/dist/artifact-eczsknc3.js +0 -3843
  485. package/dist/cli-42qhyvwx.js +0 -33
  486. package/dist/cli-bd957dgb.js +0 -153
  487. package/dist/cli-q51yprfq.js +0 -1104
  488. package/dist/cli-t1ze64h3.js +0 -811
  489. package/dist/cli-tcc4wd5d.js +0 -56471
  490. package/dist/index-9ch1n761.js +0 -1102
  491. package/src/artifact-sdk/index.ts +0 -2
  492. package/src/artifact-sdk/localtunnel.d.ts +0 -20
  493. package/src/artifact-sdk/port.ts +0 -12
  494. package/src/artifact-sdk/server.ts +0 -183
  495. package/src/artifact-sdk/tunnel.ts +0 -19
  496. package/src/commands/artifact.ts +0 -249
  497. package/src/http/ecosystem.ts +0 -77
  498. package/src/tests/artifact-commands.test.ts +0 -92
  499. package/src/tests/artifact-sdk.test.ts +0 -793
  500. package/src/tests/register-service-security.test.ts +0 -194
  501. package/src/tools/list-services.ts +0 -107
  502. package/src/tools/register-service.ts +0 -177
  503. package/src/tools/unregister-service.ts +0 -73
  504. package/src/tools/update-service-status.ts +0 -96
  505. package/templates/skills/artifacts/config.json +0 -14
  506. package/templates/skills/artifacts/content.md +0 -344
  507. package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
  508. package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
  509. package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
  510. package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
  511. /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
@@ -10,7 +10,7 @@
10
10
  import { pathToFileURL } from "node:url";
11
11
  import { toJSONSchema } from "zod";
12
12
 
13
- async function createShims(tmpdir: string): Promise<void> {
13
+ async function createShims(moduleDir: string): Promise<void> {
14
14
  const runtimeDir = process.env.SCRIPT_RUNTIME_DIR;
15
15
  const shims: [string, URL][] = [
16
16
  [
@@ -35,7 +35,7 @@ async function createShims(tmpdir: string): Promise<void> {
35
35
  ]),
36
36
  ];
37
37
  for (const [name, url] of shims) {
38
- const dir = `${tmpdir}/node_modules/${name}`;
38
+ const dir = `${moduleDir}/node_modules/${name}`;
39
39
  await Bun.$`mkdir -p ${dir}`.quiet();
40
40
  await Bun.write(`${dir}/package.json`, JSON.stringify({ type: "module", main: "index.ts" }));
41
41
  await Bun.write(`${dir}/index.ts`, `export * from ${JSON.stringify(url.href)};\n`);
@@ -52,14 +52,15 @@ if (!sourceFile || !resultFile || !tmpdir) {
52
52
  }
53
53
 
54
54
  try {
55
- await createShims(tmpdir);
55
+ // Subdirectory, not the tmpdir itself: this harness runs with cwd = tmpdir,
56
+ // and Bun (>= 1.3.12) snapshots the cwd listing at startup — a file or
57
+ // node_modules written into cwd after launch is invisible to the module
58
+ // resolver. See the same fix in eval-harness.ts.
59
+ const moduleDir = `${tmpdir}/user-module`;
60
+ await createShims(moduleDir);
56
61
 
57
62
  const source = await Bun.file(sourceFile).text();
58
- // Subdirectory, not the tmpdir itself: this harness runs with cwd = tmpdir,
59
- // and Bun (>= 1.3.12) snapshots the cwd listing at startup — a file written
60
- // into cwd after launch is invisible to the module resolver. See the same
61
- // fix in eval-harness.ts.
62
- const userModulePath = `${tmpdir}/user-module/user-script.ts`;
63
+ const userModulePath = `${moduleDir}/user-script.ts`;
63
64
  await Bun.write(userModulePath, source);
64
65
 
65
66
  let mod: Record<string, unknown>;
@@ -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
  }
@@ -0,0 +1,464 @@
1
+ import ts from "typescript";
2
+
3
+ /**
4
+ * Flags script source that would fail, or silently differ, under the quickjs
5
+ * executor. It is advisory: callers attach the findings as warnings and never
6
+ * reject on them.
7
+ */
8
+ export type QuickJSCompatRule =
9
+ | "bunGlobal"
10
+ | "process"
11
+ | "fsStdlib"
12
+ | "require"
13
+ | "workspaceRw"
14
+ | "unsupportedGlobal"
15
+ | "cryptoSubtle"
16
+ | "responseBody"
17
+ | "localeFormat"
18
+ | "hostCredential"
19
+ | "privateHost";
20
+
21
+ export type QuickJSCompatFinding = {
22
+ rule: QuickJSCompatRule;
23
+ message: string;
24
+ /** 1-based line in the script source, when the finding has one. */
25
+ line?: number;
26
+ };
27
+
28
+ export type QuickJSCompatReport = {
29
+ compatible: boolean;
30
+ findings: QuickJSCompatFinding[];
31
+ };
32
+
33
+ // Globals that Bun provides and the quickjs sandbox does not (measured against
34
+ // the QuickJS build plus quickjs-prelude.ts and quickjs-web-shims.ts).
35
+ const UNSUPPORTED_GLOBALS = new Set([
36
+ "AbortController",
37
+ "AbortSignal",
38
+ "Blob",
39
+ "Buffer",
40
+ "Event",
41
+ "EventTarget",
42
+ "File",
43
+ "FormData",
44
+ "Intl",
45
+ "ReadableStream",
46
+ "Request",
47
+ "TransformStream",
48
+ "WebSocket",
49
+ "WritableStream",
50
+ "clearImmediate",
51
+ "navigator",
52
+ "performance",
53
+ "queueMicrotask",
54
+ "setImmediate",
55
+ "structuredClone",
56
+ ]);
57
+ const RESPONSE_BODY_METHODS = new Set(["arrayBuffer", "blob", "formData", "bytes"]);
58
+ const LOCALE_METHODS = new Set(["toLocaleString", "toLocaleDateString", "toLocaleTimeString"]);
59
+ const FS_STDLIB = new Set(["glob", "grep"]);
60
+ // ctx.swarm.config values that quickjs keeps host-side (see quickjs-runner.ts).
61
+ const HOST_ONLY_CONFIG = new Set(["apiKey", "runtimeInstanceId"]);
62
+ const MAX_FINDINGS = 20;
63
+
64
+ const SCRIPT_FILE = "user-script.ts";
65
+
66
+ /** The initializer of the `const` binding a name reads; null for anything else. */
67
+ type ConstInitializer = (node: ts.Identifier) => ts.Expression | null;
68
+ // Follows at most this many consts, as in `const API = "..."; const url = `${API}/x``.
69
+ const MAX_CONST_DEPTH = 4;
70
+
71
+ /** True inside a `declare` statement, namespace or global block. */
72
+ function isAmbient(node: ts.Node): boolean {
73
+ for (let current: ts.Node | undefined = node; current; current = current.parent) {
74
+ if (
75
+ ts.canHaveModifiers(current) &&
76
+ ts.getModifiers(current)?.some((modifier) => modifier.kind === ts.SyntaxKind.DeclareKeyword)
77
+ ) {
78
+ return true;
79
+ }
80
+ }
81
+ return false;
82
+ }
83
+
84
+ /**
85
+ * Parses and binds the script with the TypeScript checker (no lib, no imports),
86
+ * so a name resolves by lexical scope: a `Buffer` parameter in one function does
87
+ * not hide a global `Buffer` read in another. A name declared only with
88
+ * `declare` (ambient) still counts as a global, because nothing defines it at run time.
89
+ */
90
+ function createScope(source: string): {
91
+ sourceFile: ts.SourceFile;
92
+ isLocal: (node: ts.Identifier) => boolean;
93
+ constInitializer: ConstInitializer;
94
+ } {
95
+ const sourceFile = ts.createSourceFile(SCRIPT_FILE, source, ts.ScriptTarget.Latest, true);
96
+ const host: ts.CompilerHost = {
97
+ getSourceFile: (name) => (name === SCRIPT_FILE ? sourceFile : undefined),
98
+ getDefaultLibFileName: () => "lib.d.ts",
99
+ writeFile: () => {},
100
+ getCurrentDirectory: () => "/",
101
+ getCanonicalFileName: (name) => name,
102
+ useCaseSensitiveFileNames: () => true,
103
+ getNewLine: () => "\n",
104
+ fileExists: (name) => name === SCRIPT_FILE,
105
+ readFile: () => undefined,
106
+ };
107
+ const program = ts.createProgram({
108
+ rootNames: [SCRIPT_FILE],
109
+ options: { noLib: true, noResolve: true, types: [], target: ts.ScriptTarget.Latest },
110
+ host,
111
+ });
112
+ const checker = program.getTypeChecker();
113
+ const isLocal = (node: ts.Identifier) => {
114
+ const symbol =
115
+ ts.isShorthandPropertyAssignment(node.parent) && node.parent.name === node
116
+ ? checker.getShorthandAssignmentValueSymbol(node.parent)
117
+ : checker.getSymbolAtLocation(node);
118
+ return Boolean(
119
+ symbol?.declarations?.some(
120
+ (declaration) => declaration.getSourceFile() === sourceFile && !isAmbient(declaration),
121
+ ),
122
+ );
123
+ };
124
+ const constInitializer: ConstInitializer = (node) => {
125
+ const declaration = checker.getSymbolAtLocation(node)?.valueDeclaration;
126
+ if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer) {
127
+ return null;
128
+ }
129
+ return ts.getCombinedNodeFlags(declaration) & ts.NodeFlags.Const
130
+ ? declaration.initializer
131
+ : null;
132
+ };
133
+ return { sourceFile, isLocal, constInitializer };
134
+ }
135
+
136
+ /** True when `node` is read as a value, not as a property name or declaration. */
137
+ function isValueReference(node: ts.Identifier): boolean {
138
+ const parent = node.parent;
139
+ if (ts.isPropertyAccessExpression(parent) && parent.name === node) return false;
140
+ if (ts.isShorthandPropertyAssignment(parent)) return true;
141
+ if ("name" in parent && (parent as { name?: ts.Node }).name === node) return false;
142
+ if (ts.isTypeOfExpression(parent)) return false;
143
+ return true;
144
+ }
145
+
146
+ function isTypeOnly(node: ts.Node): boolean {
147
+ return (
148
+ ts.isTypeNode(node) ||
149
+ ts.isInterfaceDeclaration(node) ||
150
+ ts.isTypeAliasDeclaration(node) ||
151
+ (ts.isImportDeclaration(node) && Boolean(node.importClause?.isTypeOnly))
152
+ );
153
+ }
154
+
155
+ function stdlibImportNames(node: ts.ImportDeclaration): string[] {
156
+ if (!ts.isStringLiteral(node.moduleSpecifier) || node.moduleSpecifier.text !== "stdlib")
157
+ return [];
158
+ const bindings = node.importClause?.namedBindings;
159
+ if (!bindings || !ts.isNamedImports(bindings)) return [];
160
+ return bindings.elements
161
+ .map((element) => (element.propertyName ?? element.name).text)
162
+ .filter((name) => FS_STDLIB.has(name));
163
+ }
164
+
165
+ /** Strips parentheses, `as`, `!` and `satisfies`: `(globalThis as any)` is `globalThis`. */
166
+ function unwrap(node: ts.Expression): ts.Expression {
167
+ let current = node;
168
+ while (
169
+ ts.isParenthesizedExpression(current) ||
170
+ ts.isAsExpression(current) ||
171
+ ts.isNonNullExpression(current) ||
172
+ ts.isTypeAssertionExpression(current) ||
173
+ ts.isSatisfiesExpression(current)
174
+ ) {
175
+ current = current.expression;
176
+ }
177
+ return current;
178
+ }
179
+
180
+ function isGlobalThis(node: ts.Expression): boolean {
181
+ const inner = unwrap(node);
182
+ return ts.isIdentifier(inner) && inner.text === "globalThis";
183
+ }
184
+
185
+ /** `globalThis.X` or `X` (free), as the global's name; otherwise null. */
186
+ function globalName(node: ts.Expression, isLocal: (node: ts.Identifier) => boolean): string | null {
187
+ const inner = unwrap(node);
188
+ if (ts.isIdentifier(inner)) return isLocal(inner) ? null : inner.text;
189
+ if (ts.isPropertyAccessExpression(inner) && isGlobalThis(inner.expression)) {
190
+ return inner.name.text;
191
+ }
192
+ return null;
193
+ }
194
+
195
+ function isPrivateIPv4([a = 0, b = 0, c = 0]: number[]): boolean {
196
+ return (
197
+ a === 0 ||
198
+ a === 10 ||
199
+ a === 127 ||
200
+ (a === 100 && b >= 64 && b <= 127) ||
201
+ (a === 169 && b === 254) ||
202
+ (a === 172 && b >= 16 && b <= 31) ||
203
+ (a === 192 && b === 168) ||
204
+ (a === 192 && b === 0 && c === 0) ||
205
+ (a === 198 && (b === 18 || b === 19)) ||
206
+ a >= 224
207
+ );
208
+ }
209
+
210
+ // `text` is a WHATWG-serialized IPv6 address without brackets: hex groups, at most one "::".
211
+ function isPrivateIPv6(text: string): boolean {
212
+ const [head = "", tail = ""] = text.split("::");
213
+ const left = head ? head.split(":") : [];
214
+ const right = text.includes("::") && tail ? tail.split(":") : [];
215
+ const fill = text.includes("::") ? 8 - left.length - right.length : 0;
216
+ const g = [...left, ...Array<string>(fill).fill("0"), ...right].map((part) => parseInt(part, 16));
217
+ const g0 = g[0] ?? 0;
218
+ if (g.slice(0, 6).every((part) => part === 0)) return true; // ::/96: ::, ::1
219
+ if (g.slice(0, 5).every((part) => part === 0) && g[5] === 0xffff) {
220
+ const [g6 = 0, g7 = 0] = g.slice(6);
221
+ return isPrivateIPv4([g6 >> 8, g6 & 255, g7 >> 8]); // IPv4-mapped
222
+ }
223
+ return (
224
+ (g0 & 0xfe00) === 0xfc00 || // fc00::/7 unique local
225
+ (g0 & 0xffc0) === 0xfe80 || // fe80::/10 link-local
226
+ (g0 & 0xffc0) === 0xfec0 || // fec0::/10 site-local
227
+ (g0 & 0xff00) === 0xff00 // ff00::/8 multicast
228
+ );
229
+ }
230
+
231
+ /**
232
+ * How the default egress policy sees a parsed URL hostname, statically:
233
+ * "private" for loopback names and private, link-local or reserved IP literals,
234
+ * "single-label" for a name with no dot (usually an internal service name that
235
+ * resolves to a private address). Null for anything else, including public names
236
+ * that resolve privately: only the runtime check sees DNS.
237
+ */
238
+ function staticHostClass(hostname: string): "private" | "single-label" | null {
239
+ const host = hostname.toLowerCase().replace(/\.$/, "");
240
+ if (host === "localhost" || host.endsWith(".localhost")) return "private";
241
+ if (host.startsWith("[")) return isPrivateIPv6(host.slice(1, -1)) ? "private" : null;
242
+ const v4 = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(host);
243
+ if (v4) return isPrivateIPv4(v4.slice(1).map(Number)) ? "private" : null;
244
+ return host !== "" && !host.includes(".") ? "single-label" : null;
245
+ }
246
+
247
+ /** The fetch-like call this callee names: fetch, globalThis.fetch, ctx.stdlib.fetch or fetchJson. */
248
+ function fetchCallName(callee: ts.Expression): string | null {
249
+ const inner = unwrap(callee);
250
+ if (ts.isIdentifier(inner)) {
251
+ return inner.text === "fetch" || inner.text === "fetchJson" ? inner.text : null;
252
+ }
253
+ if (!ts.isPropertyAccessExpression(inner)) return null;
254
+ const method = inner.name.text;
255
+ if (method !== "fetch" && method !== "fetchJson") return null;
256
+ const owner = unwrap(inner.expression);
257
+ if (method === "fetch" && isGlobalThis(owner)) return "fetch";
258
+ const ownerName = ts.isIdentifier(owner)
259
+ ? owner.text
260
+ : ts.isPropertyAccessExpression(owner)
261
+ ? owner.name.text
262
+ : null;
263
+ return ownerName === "stdlib" ? `ctx.stdlib.${method}` : null;
264
+ }
265
+
266
+ /**
267
+ * The fixed start of a URL argument: a literal, a const holding one, or a
268
+ * template or `+` concatenation that starts with them, through up to
269
+ * MAX_CONST_DEPTH consts. `cut` is true when the
270
+ * text stops at a dynamic part that could still extend the host, as in
271
+ * `http://intra${suffix}`; a dynamic part right after a const value cannot.
272
+ */
273
+ function staticPrefix(
274
+ node: ts.Expression,
275
+ resolve: ConstInitializer,
276
+ depth = 0,
277
+ ): { text: string; cut: boolean } | null {
278
+ const inner = unwrap(node);
279
+ if (ts.isStringLiteral(inner) || ts.isNoSubstitutionTemplateLiteral(inner)) {
280
+ return { text: inner.text, cut: false };
281
+ }
282
+ if (ts.isIdentifier(inner)) {
283
+ const initializer = depth < MAX_CONST_DEPTH ? resolve(inner) : null;
284
+ return initializer ? staticPrefix(initializer, resolve, depth + 1) : null;
285
+ }
286
+ if (ts.isTemplateExpression(inner)) {
287
+ let text = inner.head.text;
288
+ let boundary = false;
289
+ for (const span of inner.templateSpans) {
290
+ const part = staticPrefix(span.expression, resolve, depth);
291
+ if (part === null) return { text, cut: !boundary || text === "" };
292
+ if (part.cut) return { text: text + part.text, cut: true };
293
+ text += part.text + span.literal.text;
294
+ boundary = span.literal.text === "";
295
+ }
296
+ return { text, cut: false };
297
+ }
298
+ if (ts.isBinaryExpression(inner) && inner.operatorToken.kind === ts.SyntaxKind.PlusToken) {
299
+ const left = staticPrefix(inner.left, resolve, depth);
300
+ if (left === null || left.cut) return left;
301
+ const right = staticPrefix(inner.right, resolve, depth);
302
+ if (right === null) return { text: left.text, cut: !ts.isIdentifier(unwrap(inner.left)) };
303
+ return { text: left.text + right.text, cut: right.cut };
304
+ }
305
+ return null;
306
+ }
307
+
308
+ /** The URL argument's host when the source fixes it, parsed with the host URL parser. */
309
+ function literalUrl(arg: ts.Expression | undefined, resolve: ConstInitializer): URL | null {
310
+ if (!arg) return null;
311
+ const prefix = staticPrefix(arg, resolve);
312
+ if (!prefix) return null;
313
+ // A cut prefix fixes the host only once the authority has ended.
314
+ if (prefix.cut && !/^[a-z][a-z0-9+.-]*:\/\/[^/?#]*[/?#]/i.test(prefix.text)) return null;
315
+ try {
316
+ return new URL(prefix.text);
317
+ } catch {
318
+ return null;
319
+ }
320
+ }
321
+
322
+ export function checkQuickJSCompat(
323
+ source: string,
324
+ options: { fsMode?: string } = {},
325
+ ): QuickJSCompatReport {
326
+ const findings: QuickJSCompatFinding[] = [];
327
+ const seen = new Set<string>();
328
+ const { sourceFile, isLocal, constInitializer } = createScope(source);
329
+ const add = (rule: QuickJSCompatRule, message: string, node?: ts.Node) => {
330
+ if (seen.has(`${rule}:${message}`)) return;
331
+ seen.add(`${rule}:${message}`);
332
+ const line = node
333
+ ? sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1
334
+ : undefined;
335
+ findings.push(line === undefined ? { rule, message } : { rule, message, line });
336
+ };
337
+
338
+ if (options.fsMode === "workspace-rw") {
339
+ add("workspaceRw", "fsMode workspace-rw is not available under quickjs");
340
+ }
341
+
342
+ const reportGlobal = (name: string, node: ts.Node) => {
343
+ if (name === "Bun") add("bunGlobal", "Bun.* is not available under quickjs", node);
344
+ else if (name === "process") add("process", "process is not available under quickjs", node);
345
+ else if (UNSUPPORTED_GLOBALS.has(name)) {
346
+ add("unsupportedGlobal", `${name} is not available under quickjs`, node);
347
+ }
348
+ };
349
+
350
+ const visit = (node: ts.Node) => {
351
+ if (isTypeOnly(node)) return;
352
+
353
+ if (
354
+ ts.isIdentifier(node) &&
355
+ (node.text === "Bun" || node.text === "process" || UNSUPPORTED_GLOBALS.has(node.text)) &&
356
+ isValueReference(node) &&
357
+ !isLocal(node)
358
+ ) {
359
+ reportGlobal(node.text, node);
360
+ }
361
+
362
+ if (ts.isPropertyAccessExpression(node)) {
363
+ const member = node.name.text;
364
+ const owner = globalName(node.expression, isLocal);
365
+ if (isGlobalThis(node.expression) && !ts.isTypeOfExpression(node.parent)) {
366
+ reportGlobal(member, node);
367
+ }
368
+ const parent = unwrap(node.expression);
369
+ if (
370
+ HOST_ONLY_CONFIG.has(member) &&
371
+ ts.isPropertyAccessExpression(parent) &&
372
+ parent.name.text === "config"
373
+ ) {
374
+ add(
375
+ "hostCredential",
376
+ `ctx.swarm.config.${member} is host-only under quickjs; ctx.swarm calls use it for you`,
377
+ node,
378
+ );
379
+ }
380
+ if (member === "subtle" && owner === "crypto") {
381
+ add("cryptoSubtle", "crypto.subtle is not available under quickjs", node);
382
+ }
383
+ if (
384
+ FS_STDLIB.has(member) &&
385
+ ts.isPropertyAccessExpression(unwrap(node.expression)) &&
386
+ (unwrap(node.expression) as ts.PropertyAccessExpression).name.text === "stdlib"
387
+ ) {
388
+ add("fsStdlib", `ctx.stdlib.${member} needs filesystem access, which quickjs lacks`, node);
389
+ }
390
+ }
391
+
392
+ if (ts.isImportDeclaration(node)) {
393
+ for (const name of stdlibImportNames(node)) {
394
+ add("fsStdlib", `stdlib ${name} needs filesystem access, which quickjs lacks`, node);
395
+ }
396
+ }
397
+
398
+ if (
399
+ ts.isVariableDeclaration(node) &&
400
+ ts.isObjectBindingPattern(node.name) &&
401
+ node.initializer &&
402
+ ts.isPropertyAccessExpression(node.initializer) &&
403
+ node.initializer.name.text === "stdlib"
404
+ ) {
405
+ for (const element of node.name.elements) {
406
+ const name = (element.propertyName ?? element.name).getText(sourceFile);
407
+ if (FS_STDLIB.has(name)) {
408
+ add("fsStdlib", `ctx.stdlib.${name} needs filesystem access, which quickjs lacks`, node);
409
+ }
410
+ }
411
+ }
412
+
413
+ if (ts.isCallExpression(node)) {
414
+ const callee = node.expression;
415
+ const fetchName = fetchCallName(callee);
416
+ const url = fetchName ? literalUrl(node.arguments[0], constInitializer) : null;
417
+ const hostClass =
418
+ url && (url.protocol === "http:" || url.protocol === "https:")
419
+ ? staticHostClass(url.hostname)
420
+ : null;
421
+ if (url && hostClass) {
422
+ add(
423
+ "privateHost",
424
+ `${fetchName} to ${url.host} (${hostClass} host) depends on the egress policy: quickjs refuses private hosts unless the operator allows them`,
425
+ node,
426
+ );
427
+ }
428
+ if (ts.isIdentifier(callee) && callee.text === "require" && !isLocal(callee)) {
429
+ add("require", "require() is not supported; use an import", node);
430
+ }
431
+ if (ts.isPropertyAccessExpression(callee)) {
432
+ const method = callee.name.text;
433
+ if (RESPONSE_BODY_METHODS.has(method) && node.arguments.length === 0) {
434
+ add(
435
+ "responseBody",
436
+ `.${method}() on a fetch Response is not available under quickjs (text() and json() are)`,
437
+ node,
438
+ );
439
+ }
440
+ if (LOCALE_METHODS.has(method) && node.arguments.length > 0) {
441
+ add(
442
+ "localeFormat",
443
+ `${method}(locale, options) ignores its arguments under quickjs (no Intl)`,
444
+ node,
445
+ );
446
+ }
447
+ }
448
+ }
449
+
450
+ ts.forEachChild(node, visit);
451
+ };
452
+ visit(sourceFile);
453
+
454
+ return { compatible: findings.length === 0, findings: findings.slice(0, MAX_FINDINGS) };
455
+ }
456
+
457
+ /** One human-readable line per finding, for `warnings` arrays. */
458
+ export function quickJSCompatWarnings(report: QuickJSCompatReport, label?: string): string[] {
459
+ const prefix = label ? `${label}: ` : "";
460
+ return report.findings.map(
461
+ (finding) =>
462
+ `${prefix}quickjs compat (${finding.rule}${finding.line ? `, line ${finding.line}` : ""}): ${finding.message}`,
463
+ );
464
+ }
@@ -89,6 +89,7 @@ export const SDK_TOOL_NAME_MAP = {
89
89
  // ── model catalog ──
90
90
  modelCatalog_refresh: "model-catalog-refresh", // external: fetches models.dev
91
91
  modelCatalog_overlayUpsert: "model-catalog-overlay-upsert",
92
+ modelProfile_list: "list-model-profiles",
92
93
 
93
94
  // ── slack ──
94
95
  slack_read: "slack-read",
@@ -104,6 +105,14 @@ export const SDK_TOOL_NAME_MAP = {
104
105
  slack_delete: "slack-delete", // external: mutates Slack, destructive
105
106
  slack_update: "slack-update", // external: mutates Slack
106
107
 
108
+ // ── chat sdk ──
109
+ chat_reply: "chat-reply", // external: sends to the task's chat thread
110
+ chat_post: "chat-post", // external: sends to a chat platform
111
+ chat_openDm: "chat-open-dm", // external: opens a platform DM
112
+ chat_readThread: "chat-read-thread",
113
+ chat_registerChannel: "register-chat-channel",
114
+ chat_unregisterChannel: "unregister-chat-channel", // destructive
115
+
107
116
  // ── messaging (internal) ──
108
117
  message_read: "read-messages",
109
118
  message_post: "post-message",
@@ -115,12 +124,6 @@ export const SDK_TOOL_NAME_MAP = {
115
124
  context_history: "context-history",
116
125
  context_diff: "context-diff",
117
126
 
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
127
  // ── workflows ──
125
128
  workflow_list: "list-workflows",
126
129
  workflow_get: "get-workflow",
@@ -187,6 +190,9 @@ export const SDK_TOOL_NAME_MAP = {
187
190
  // ── human input ──
188
191
  request_humanInput: "request-human-input",
189
192
  approval_cancel: "cancel-approval-request", // destructive
193
+
194
+ // ── decisions ──
195
+ systemOne_decide: "system-one-decide",
190
196
  } as const;
191
197
 
192
198
  export const SDK_ALLOWLIST = Object.keys(SDK_TOOL_NAME_MAP) as Array<
@@ -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 {