@desplega.ai/agent-swarm 1.165.0 → 1.167.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 (296) hide show
  1. package/dist/acp-adapter-zpvy6321.js +34 -0
  2. package/dist/{actions-jna0b3wm.js → actions-fq2zrwtf.js} +30 -34
  3. package/dist/{amp-adapter-0eve81pz.js → amp-adapter-5gbk7501.js} +7 -7
  4. package/dist/{anthropic-messages-hst62ws9.js → anthropic-messages-13yn502s.js} +4 -4
  5. package/dist/{app-75hm5cfa.js → app-nctetn1e.js} +11 -11
  6. package/dist/{assistant-yzd51j33.js → assistant-0aq8gjvj.js} +31 -35
  7. package/dist/{azure-openai-responses-mh8tvf78.js → azure-openai-responses-9st34pfz.js} +5 -5
  8. package/dist/{boot-reembed-z158xq32.js → boot-reembed-1ze5853n.js} +14 -16
  9. package/dist/{boot-reembed-2ex2mcsh.js → boot-reembed-fmp5ww69.js} +15 -16
  10. package/dist/boot-scrub-sweep-cbp8xd4e.js +212 -0
  11. package/dist/{boot-seeds-2bmnh18p.js → boot-seeds-22tx8a53.js} +13 -12
  12. package/dist/{claude-adapter-jbj1mycz.js → claude-adapter-0jhgeh1d.js} +25 -25
  13. package/dist/{claude-managed-adapter-17ggz09t.js → claude-managed-adapter-tzwxy803.js} +5 -5
  14. package/dist/{claude-managed-setup-ptm1nzm2.js → claude-managed-setup-nrhfx5b0.js} +5 -5
  15. package/dist/{claude-sdk-session-9re1g7r2.js → claude-sdk-session-wh77rh83.js} +2632 -2614
  16. package/dist/{cli-zsh093hk.js → cli-014vns2y.js} +63 -1
  17. package/dist/{cli-qvfk83fy.js → cli-13xwcqvj.js} +2 -2
  18. package/dist/{cli-8gpbwy09.js → cli-1yrcfa5s.js} +5 -5
  19. package/dist/{cli-xtgtyafv.js → cli-577bxkf6.js} +212 -451
  20. package/dist/{cli-ma3zvh39.js → cli-5qkcdv8c.js} +6118 -5874
  21. package/dist/{cli-cwxhbf43.js → cli-5t5my0h8.js} +85 -2
  22. package/dist/{cli-zvckv750.js → cli-69egj654.js} +2 -2
  23. package/dist/{cli-9xb89xca.js → cli-6bpvv8h4.js} +9 -9
  24. package/dist/{cli-90v942q1.js → cli-6qxmjpem.js} +8 -8
  25. package/dist/{cli-9866bd07.js → cli-6vfz44sr.js} +1 -1
  26. package/dist/{cli-32bca7nr.js → cli-7avy4v8w.js} +1 -1
  27. package/dist/{cli-xb3c6aat.js → cli-7mhy3ths.js} +21 -18
  28. package/dist/{cli-q38n4bq0.js → cli-95zs84qw.js} +3 -3
  29. package/dist/cli-a35hzdve.js +33 -0
  30. package/dist/{cli-x3x0qwky.js → cli-bxqez1p0.js} +51 -23
  31. package/dist/{cli-prt9emct.js → cli-c2tpw9ck.js} +3 -3
  32. package/dist/{cli-0n4fasz0.js → cli-c8r99akr.js} +16 -16
  33. package/dist/{cli-5anb0ev3.js → cli-cexctgn5.js} +89 -26
  34. package/dist/{cli-bns5c8k9.js → cli-cf2vgn9d.js} +105 -91
  35. package/dist/{cli-ng97fjq7.js → cli-cmxkbzzs.js} +33 -7
  36. package/dist/{cli-nexwh8zg.js → cli-g7k7zbcz.js} +12 -5
  37. package/dist/{cli-mmzwwptd.js → cli-hf5s9pgf.js} +1 -1
  38. package/dist/{cli-nvvfd8bq.js → cli-jbzbr36n.js} +4091 -3793
  39. package/dist/{cli-zn2v3t8v.js → cli-jvmtxqtc.js} +27 -15
  40. package/dist/{cli-pkke6geq.js → cli-km4x66j0.js} +83 -65
  41. package/dist/cli-kw0jcfje.js +516 -0
  42. package/dist/{cli-28smfvbn.js → cli-m7vmeepg.js} +32 -19
  43. package/dist/{cli-hpryr6em.js → cli-mb75wpxf.js} +1 -1
  44. package/dist/{cli-qdv8kgz7.js → cli-mkdsy1nq.js} +14018 -3333
  45. package/dist/{cli-b0f70z24.js → cli-mn8qkd8v.js} +1 -1
  46. package/dist/{cli-420bdgw0.js → cli-mv2520nm.js} +1 -1
  47. package/dist/{cli-n9ehc28t.js → cli-mxry91sa.js} +31 -10
  48. package/dist/{cli-wfajtmf7.js → cli-mxvnnv5q.js} +596 -13
  49. package/dist/cli-nkqjj42q.js +104 -0
  50. package/dist/{cli-e7t4snpa.js → cli-p8rt8spp.js} +5 -5
  51. package/dist/{cli-gh5yqzpe.js → cli-pkj1w46r.js} +12 -7
  52. package/dist/cli-q1vnz8wv.js +96 -0
  53. package/dist/{cli-fj86xr3c.js → cli-qd97v6z2.js} +2 -2
  54. package/dist/{cli-ba66wyhy.js → cli-qzmzwegq.js} +60 -20
  55. package/dist/{cli-5b2fjjzh.js → cli-r7eeddkq.js} +14 -9
  56. package/dist/{cli-8ssjez7e.js → cli-rhy7z1rp.js} +22 -11
  57. package/dist/{cli-4mevd1hf.js → cli-s9y81s7j.js} +5 -5
  58. package/dist/{cli-59jn5twa.js → cli-tc5zec7v.js} +7 -7
  59. package/dist/{cli-ttbsse3f.js → cli-tmhsxhb8.js} +1 -1
  60. package/dist/{cli-k6xx3pve.js → cli-tx2zvn23.js} +4 -4
  61. package/dist/{cli-pjxnr1jn.js → cli-ty4bzkqr.js} +5 -5
  62. package/dist/{cli-nfygw434.js → cli-v1pwxreq.js} +55 -52
  63. package/dist/{cli-ftry7975.js → cli-v1w7pbd8.js} +3 -2
  64. package/dist/{cli-10zmp1p7.js → cli-vr5avem2.js} +27 -32
  65. package/dist/{cli-bzr0ftht.js → cli-wnb9b2g3.js} +19 -0
  66. package/dist/cli-wt7ccy4r.js +2654 -0
  67. package/dist/{cli-50eg13rj.js → cli-wydz3feg.js} +549 -321
  68. package/dist/{cli-krqm5f11.js → cli-xezn9nkh.js} +16 -13
  69. package/dist/{cli-8kt0bmgx.js → cli-xf713zz0.js} +2 -2
  70. package/dist/{cli-x7afk5wm.js → cli-xvc3q9br.js} +1 -1
  71. package/dist/{cli-9s3h836g.js → cli-xvdgasgy.js} +1 -1
  72. package/dist/{cli-j0pdrmwg.js → cli-y0kjpfm9.js} +3 -3
  73. package/dist/{cli-6zcfw0x7.js → cli-y195hv1a.js} +1 -1
  74. package/dist/{cli-amwhs8h2.js → cli-ykt8f7va.js} +22 -9
  75. package/dist/{cli-1kzfvd1z.js → cli-ymmc1zxg.js} +15 -11
  76. package/dist/{cli-xnzrzets.js → cli-ypgba1a8.js} +2 -2
  77. package/dist/{cli-bdv39kgj.js → cli-z1dqhc9y.js} +31 -20
  78. package/dist/{cli-fw6vdcq5.js → cli-zp67qg5x.js} +34 -1
  79. package/dist/{cli-qbksc292.js → cli-zy39d433.js} +2 -0
  80. package/dist/cli.js +36 -32
  81. package/dist/{cloudflare-workers-ai-system-one-tt484t61.js → cloudflare-workers-ai-system-one-sta45jf9.js} +7 -5
  82. package/dist/{codex-adapter-3qnxshje.js → codex-adapter-cgesnjkr.js} +20 -20
  83. package/dist/{codex-login-brkxhhdg.js → codex-login-g1cyt5zm.js} +2 -2
  84. package/dist/{codex-session-runner-612wnapp.js → codex-session-runner-8kd7ddhr.js} +20 -20
  85. package/dist/{commands-2ybfcxkj.js → commands-h6zaaxym.js} +11 -10
  86. package/dist/{cursor-adapter-p3jgdehv.js → cursor-adapter-v8mm6bp5.js} +7 -7
  87. package/dist/{db-f4ans0jj.js → db-qg3myn53.js} +13 -10
  88. package/dist/{devin-adapter-dhzt01ff.js → devin-adapter-bffjj5n4.js} +2 -2
  89. package/dist/{dispatcher-pk182apd.js → dispatcher-7vnwj9qw.js} +28 -32
  90. package/dist/{dsh-adapter-7twaeps1.js → dsh-adapter-tz6hfp5r.js} +7 -7
  91. package/dist/{e2b-y8t3jzyz.js → e2b-nd50eccg.js} +1 -1
  92. package/dist/{easter-egg-3d-mtpnw06s.js → easter-egg-3d-66zxervv.js} +2 -2
  93. package/dist/{event-bus-w7ac4n3c.js → event-bus-vnfthafg.js} +2 -2
  94. package/dist/{execute-s4ccjq3n.js → execute-h4jgevyw.js} +61 -11
  95. package/dist/{google-generative-ai-d6nphg3q.js → google-generative-ai-b8zxrpax.js} +5 -5
  96. package/dist/{google-vertex-cpshkref.js → google-vertex-nrdd697t.js} +5 -5
  97. package/dist/grok-adapter-jdt2dz2s.js +39 -0
  98. package/dist/{handlers-g2wnr4t9.js → handlers-2qtkpncr.js} +31 -35
  99. package/dist/{hook-f7jt9vnm.js → hook-51yfcgsv.js} +48 -39
  100. package/dist/{hook-bbdpnkb4.js → hook-qnbdgwvd.js} +15 -17
  101. package/dist/{http-w40q4w94.js → http-jsmtag08.js} +536 -231
  102. package/dist/{index-056j5kzn.js → index-2t9kesn1.js} +13 -12
  103. package/dist/{index-cj1r9q83.js → index-bt8wkv1w.js} +29 -33
  104. package/dist/{index-7n70jwbb.js → index-cx1sb9bq.js} +42 -35
  105. package/dist/{index-9bfssf54.js → index-ekywyv2v.js} +28 -32
  106. package/dist/{index-fdk1t4d6.js → index-n0rxa4ca.js} +11962 -9900
  107. package/dist/{index-k8xc083e.js → index-t4g06w93.js} +28 -32
  108. package/dist/{keepalive-1tj10tf4.js → keepalive-4aezx4bj.js} +16 -12
  109. package/dist/{lead-st0bg7v4.js → lead-r44bkpm5.js} +52 -56
  110. package/dist/{llama-cpp-classify-tgj35k8d.js → llama-cpp-classify-6erb7wwv.js} +3 -1
  111. package/dist/{maintenance-nz71zats.js → maintenance-grz5jrzh.js} +12 -13
  112. package/dist/{mistral-conversations-8445ddjn.js → mistral-conversations-059y51zt.js} +4 -4
  113. package/dist/{node-f0ykebbv.js → node-qm9eb6z0.js} +25 -7
  114. package/dist/{oauth-refresh-sweep-aefzwvvq.js → oauth-refresh-sweep-wm4ctjfj.js} +15 -11
  115. package/dist/{onboard-kgpr9mbn.js → onboard-v60zgqf0.js} +2 -2
  116. package/dist/{openai-codex-responses-9ynm88zy.js → openai-codex-responses-jzxkta9b.js} +8 -7
  117. package/dist/{openai-completions-nhqwjmaw.js → openai-completions-663yncfq.js} +4 -4
  118. package/dist/openai-decisions-vj9nkpf8.js +162 -0
  119. package/dist/{openai-responses-xx1c4kgm.js → openai-responses-m3g43rrt.js} +5 -5
  120. package/dist/{opencode-adapter-0c8e70dk.js → opencode-adapter-yjyqynzf.js} +8 -8
  121. package/dist/{openrouter-images-8yx3487g.js → openrouter-images-kr60n6b9.js} +1 -1
  122. package/dist/{otel-impl-x8zp4y5a.js → otel-impl-ghh4dyf8.js} +2 -2
  123. package/dist/{pi-messages-vxdt8v7j.js → pi-messages-xszk613n.js} +1 -1
  124. package/dist/{pi-mono-adapter-t280ah5c.js → pi-mono-adapter-0eg8kw2c.js} +69 -52
  125. package/dist/{pricing-refresh-9e0q7cwk.js → pricing-refresh-mjrqvnvw.js} +12 -11
  126. package/dist/{rbac-roles-790j3ga8.js → rbac-roles-axv4d74x.js} +11 -10
  127. package/dist/{rbac-roles-kcp6zge2.js → rbac-roles-fd5tskj9.js} +11 -10
  128. package/dist/{render-v2-tch4nefj.js → render-v2-k50j33qd.js} +11 -11
  129. package/dist/{runtime-v2t1r79e.js → runtime-h9ha1mq6.js} +4 -4
  130. package/dist/{setup-rcm303ns.js → setup-4syh0pd2.js} +2 -2
  131. package/dist/{typesafe-system-one-datfr82p.js → typesafe-system-one-e988vty7.js} +7 -5
  132. package/dist/{virtual-modules-wm8mxdxx.js → virtual-modules-ftr9kwe8.js} +11 -11
  133. package/dist/{work-objects-ctg7t70w.js → work-objects-jcdbg8rr.js} +32 -36
  134. package/dist/{worker-5dp0xm55.js → worker-x8j8c9sx.js} +52 -56
  135. package/dist/{x-v3yw66zs.js → x-ma4gnfgy.js} +2 -2
  136. package/openapi.json +5 -2
  137. package/package.json +15 -11
  138. package/src/be/automation-preflight.ts +9 -4
  139. package/src/be/boot-scrub-sweep.ts +302 -0
  140. package/src/be/crypto/key-bootstrap.ts +1 -1
  141. package/src/be/db/approvals.ts +15 -1
  142. package/src/be/db/codex-oauth-device-flows.ts +40 -0
  143. package/src/be/db/config-secrets.ts +31 -0
  144. package/src/be/db/runtime.ts +4 -0
  145. package/src/be/db/script-runs.ts +15 -0
  146. package/src/be/db/tasks/write.ts +1 -1
  147. package/src/be/db-queries/mcp-oauth.ts +5 -0
  148. package/src/be/db-queries/oauth.ts +77 -0
  149. package/src/be/db.ts +162 -59
  150. package/src/be/events.ts +17 -1
  151. package/src/be/memory/index-content.ts +2 -2
  152. package/src/be/memory/providers/openai-embedding.ts +7 -2
  153. package/src/be/memory/providers/sqlite-store.ts +63 -11
  154. package/src/be/memory/raters/llm-summarizer.ts +7 -2
  155. package/src/be/memory/types.ts +14 -0
  156. package/src/be/migrations/201_workflow_replay_columns.sql +10 -0
  157. package/src/be/migrations/202_codex_oauth_device_flows.sql +24 -0
  158. package/src/be/modelsdev-cache.json +61 -0
  159. package/src/be/scripts/db.ts +28 -4
  160. package/src/be/scripts/source-secrets.ts +37 -0
  161. package/src/be/scrub-json.ts +32 -0
  162. package/src/be/sealed-json.ts +59 -0
  163. package/src/be/secret-registry.ts +131 -0
  164. package/src/be/seed-pricing.ts +84 -53
  165. package/src/be/swarm-config-guard.ts +13 -0
  166. package/src/be/workflow-replay.ts +77 -0
  167. package/src/commands/provider-credentials.ts +28 -5
  168. package/src/commands/runner.ts +7 -12
  169. package/src/heartbeat/heartbeat.ts +91 -19
  170. package/src/hooks/hook.ts +72 -27
  171. package/src/http/codex-oauth-device.ts +8 -10
  172. package/src/http/db-query-bounded.ts +3 -0
  173. package/src/http/db-query-shared.ts +107 -15
  174. package/src/http/db-query.ts +10 -2
  175. package/src/http/index.ts +23 -6
  176. package/src/http/mcp.ts +5 -0
  177. package/src/http/onboarding.ts +2 -0
  178. package/src/http/script-runs.ts +9 -1
  179. package/src/http/scripts.ts +15 -0
  180. package/src/http/workflows.ts +3 -2
  181. package/src/oauth/mcp-wrapper.ts +1 -1
  182. package/src/providers/acp-adapter.ts +25 -11
  183. package/src/providers/acp-target-catalog.ts +35 -1
  184. package/src/providers/acp-targets.ts +78 -7
  185. package/src/providers/amp-adapter.ts +1 -1
  186. package/src/providers/claude-adapter.ts +26 -0
  187. package/src/providers/codex-adapter.ts +30 -3
  188. package/src/providers/codex-oauth/auth-json.ts +21 -4
  189. package/src/providers/codex-oauth/types.ts +2 -0
  190. package/src/providers/cursor-adapter.ts +1 -1
  191. package/src/providers/dsh-adapter.ts +10 -1
  192. package/src/providers/grok-adapter.ts +18 -2
  193. package/src/providers/opencode-adapter.ts +21 -5
  194. package/src/providers/pi-mono-extension.ts +56 -25
  195. package/src/providers/pricing-sources.md +2 -0
  196. package/src/script-workflows/supervisor.ts +11 -2
  197. package/src/scripts-runtime/eval-harness.ts +2 -12
  198. package/src/scripts-runtime/executors/quickjs-bundle.ts +152 -0
  199. package/src/scripts-runtime/executors/quickjs-prelude.ts +285 -0
  200. package/src/scripts-runtime/executors/quickjs-runner.ts +580 -0
  201. package/src/scripts-runtime/executors/quickjs-worker.ts +81 -0
  202. package/src/scripts-runtime/executors/quickjs.ts +196 -0
  203. package/src/scripts-runtime/executors/registry.ts +2 -0
  204. package/src/scripts-runtime/executors/sourcemap.ts +79 -0
  205. package/src/scripts-runtime/script-error-hints.ts +14 -0
  206. package/src/server.ts +66 -4
  207. package/src/tests/acp-adapter.test.ts +277 -12
  208. package/src/tests/boot-scrub-sweep.test.ts +390 -0
  209. package/src/tests/check-text-columns.test.ts +145 -0
  210. package/src/tests/ci-unit-test-report.test.ts +73 -0
  211. package/src/tests/claude-default-route.test.ts +75 -0
  212. package/src/tests/claude-hook-output.test.ts +233 -0
  213. package/src/tests/claude-sdk-process.fixture.ts +13 -2
  214. package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +4 -2
  215. package/src/tests/codex-adapter.test.ts +166 -26
  216. package/src/tests/codex-oauth-auth-timestamps.test.ts +76 -0
  217. package/src/tests/codex-oauth-device.test.ts +23 -37
  218. package/src/tests/codex-oauth.test.ts +4 -1
  219. package/src/tests/context-window.test.ts +2 -2
  220. package/src/tests/credential-check.test.ts +51 -1
  221. package/src/tests/db-query-denylist.test.ts +202 -0
  222. package/src/tests/db-task-read-contract.test.ts +1 -0
  223. package/src/tests/db-task-write-contract.test.ts +1 -0
  224. package/src/tests/dsh-adapter.test.ts +23 -1
  225. package/src/tests/enabled-tools.test.ts +269 -0
  226. package/src/tests/entrypoint-acp-target-binary.test.ts +31 -1
  227. package/src/tests/entrypoint-codex-oauth-seed.test.ts +12 -0
  228. package/src/tests/events-scrub.test.ts +88 -0
  229. package/src/tests/fixtures/secret-corpus.ts +320 -0
  230. package/src/tests/grok-adapter.test.ts +13 -0
  231. package/src/tests/haiku-5-5-pricing.test.ts +38 -0
  232. package/src/tests/heartbeat-checklist.test.ts +158 -1
  233. package/src/tests/onboarding.test.ts +44 -0
  234. package/src/tests/opencode-adapter.test.ts +66 -3
  235. package/src/tests/opencode-plugin.test.ts +37 -0
  236. package/src/tests/openrouter-attribution-call-sites.test.ts +204 -0
  237. package/src/tests/openrouter-base-url.test.ts +30 -39
  238. package/src/tests/pi-mono-extension.test.ts +161 -2
  239. package/src/tests/pricing-refresh.test.ts +70 -1
  240. package/src/tests/reasoning-effort.test.ts +3 -1
  241. package/src/tests/script-connections.test.ts +5 -0
  242. package/src/tests/script-executor-conformance.test.ts +3 -0
  243. package/src/tests/script-executor-quickjs.test.ts +442 -0
  244. package/src/tests/script-executor-registry.test.ts +6 -1
  245. package/src/tests/script-runs-http.test.ts +88 -1
  246. package/src/tests/script-runs-scrub.test.ts +275 -0
  247. package/src/tests/scripts-http.test.ts +82 -1
  248. package/src/tests/scrubbed-text-12e.test.ts +289 -0
  249. package/src/tests/sealed-key-guard.test.ts +166 -0
  250. package/src/tests/secret-canary-sweep.test.ts +958 -0
  251. package/src/tests/secret-registry.test.ts +355 -0
  252. package/src/tests/secret-rules.test.ts +230 -0
  253. package/src/tests/secret-scrubber.test.ts +3 -2
  254. package/src/tests/telemetry-trigger.test.ts +12 -1
  255. package/src/tests/workflow-llm.test.ts +14 -0
  256. package/src/tests/workflow-replay.test.ts +518 -0
  257. package/src/tests/workflow-scrub.test.ts +242 -0
  258. package/src/tests/workflow-system-one-decision-providers.test.ts +33 -0
  259. package/src/tools/db-query.ts +1 -1
  260. package/src/tools/inject-learning.ts +1 -1
  261. package/src/tools/request-human-input.ts +7 -2
  262. package/src/tools/workflows/get-workflow-run.ts +3 -2
  263. package/src/types.ts +1 -1
  264. package/src/utils/enabled-tools.ts +27 -0
  265. package/src/utils/internal-ai/complete-structured.ts +11 -3
  266. package/src/utils/openrouter-base-url.ts +23 -0
  267. package/src/utils/secret-rules.generated.ts +2055 -0
  268. package/src/utils/secret-scrubber.ts +363 -29
  269. package/src/workflows/engine.ts +39 -4
  270. package/src/workflows/executors/raw-llm.ts +1 -0
  271. package/src/workflows/executors/system-one-decision.ts +2 -0
  272. package/src/workflows/executors/validate.ts +1 -0
  273. package/src/workflows/executors/workflow-llm.ts +9 -2
  274. package/src/workflows/recovery.ts +10 -1
  275. package/src/workflows/resume.ts +62 -3
  276. package/src/workflows/retry-poller.ts +3 -0
  277. package/templates/skills/agent-browser/SKILL.md +2 -0
  278. package/templates/skills/agent-browser/content.md +2 -0
  279. package/templates/skills/code-quality/content.md +1 -0
  280. package/templates/skills/heartbeat-runbook/content.md +1 -1
  281. package/templates/skills/work-on-task/SKILL.md +4 -0
  282. package/templates/skills/work-on-task/content.md +4 -0
  283. package/templates/skills/workflow-iterate/content.md +9 -0
  284. package/dist/acp-adapter-w6zws6me.js +0 -23
  285. package/dist/boot-scrub-logs-246yn076.js +0 -99
  286. package/dist/cli-3a4m1aws.js +0 -572
  287. package/dist/cli-3dpj7atn.js +0 -11
  288. package/dist/cli-a87b04k8.js +0 -951
  289. package/dist/cli-cvk6yzw5.js +0 -40
  290. package/dist/cli-gvcgmx69.js +0 -183
  291. package/dist/cli-h1spv8v4.js +0 -427
  292. package/dist/cli-jqt9hrnz.js +0 -168
  293. package/dist/cli-yhmwmv0g.js +0 -9281
  294. package/dist/grok-adapter-yt9pab3k.js +0 -29
  295. package/src/be/boot-scrub-logs.ts +0 -132
  296. package/dist/{codex-hook-d2rkvf39.js → codex-hook-15dgc4cb.js} +1 -1
@@ -178,6 +178,8 @@ and heartbeat-classified roots are omitted, and the metrics remain separate.
178
178
  - **Codex usage:** the app-server reports cumulative token counters, including cache writes.
179
179
  The adapter calculates each turn's delta before adding it to the session total.
180
180
  This prevents repeated billing of earlier turns when the adapter processes queued input.
181
+ Context occupancy is separate: it comes from the per-request `tokenUsage.last`
182
+ snapshot (and `modelContextWindow` when present), never from the turn delta.
181
183
  - **Claude breakdown validity is all-or-nothing:** the claude adapter drops the
182
184
  entire `modelUsage` breakdown when any entry carries a missing, non-finite,
183
185
  or negative token counter — zero-filling would let the server price a
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  getRunningScriptRuns,
3
3
  getScriptRun,
4
+ getScriptRunExecutionArgs,
4
5
  updateScriptRun,
5
6
  updateScriptRunIfRunning,
6
7
  } from "../be/db";
7
8
  import type { ScriptRun } from "../types";
8
9
  import { getApiKey } from "../utils/api-key";
10
+ import { scrubSecrets } from "../utils/secret-scrubber";
9
11
  import {
10
12
  localProcessScriptExecutor,
11
13
  type ScriptExecutionHandle,
@@ -44,7 +46,10 @@ export async function startScriptRunProcess(
44
46
  );
45
47
  }
46
48
 
47
- const execution = await scriptExecutor.start({ run, baseUrl, apiKey });
49
+ // `run.args` is the redacted view; launch with the exact sealed value.
50
+ const sealedArgs = await getScriptRunExecutionArgs(run.id);
51
+ const args = sealedArgs === undefined ? run.args : sealedArgs;
52
+ const execution = await scriptExecutor.start({ run: { ...run, args }, baseUrl, apiKey });
48
53
  managed.set(run.id, { execution });
49
54
  await updateScriptRun(run.id, {
50
55
  status: "running",
@@ -57,8 +62,12 @@ export async function startScriptRunProcess(
57
62
  const current = await getScriptRun(run.id);
58
63
  if (current && current.status === "running") {
59
64
  if (exitCode !== 0) {
65
+ // Script stderr can echo whatever the script printed; scrub at the
66
+ // log egress. The `error` column below is scrubbed by the DB writer.
60
67
  console.error(
61
- `[script-workflows] run ${run.id} subprocess exited ${exitCode}: ${stderr.trim() || "(no stderr)"}`,
68
+ scrubSecrets(
69
+ `[script-workflows] run ${run.id} subprocess exited ${exitCode}: ${stderr.trim() || "(no stderr)"}`,
70
+ ),
62
71
  );
63
72
  }
64
73
  // Guarded write: the read above is followed by an await, so the
@@ -1,6 +1,7 @@
1
1
  import { buildCtx } from "./ctx";
2
2
  import { patchFetchWithEgressSubstitution } from "./egress-secrets";
3
3
  import type { SwarmConfigPayload } from "./executors/types";
4
+ import { ctxSignatureHintFor } from "./script-error-hints";
4
5
  import { SwarmConfig } from "./swarm-config";
5
6
 
6
7
  function requiredEnv(name: string): string {
@@ -20,14 +21,6 @@ type StructuredError = {
20
21
  ctxSignatureHint?: string;
21
22
  };
22
23
 
23
- // Matches runtime errors that look like a swapped/misused (args, ctx) signature,
24
- // e.g. destructuring `ctx.api`/`ctx.kv`/`ctx.fetchJson`/`ctx.log` off `undefined`/`null`
25
- // because the script read them off `args` instead.
26
- const CTX_UNDEFINED_ACCESS_RE = /cannot read propert(?:y|ies)(?: .*)? of (?:undefined|null)/i;
27
- const CTX_MEMBER_RE = /\b(api|kv|fetchJson|log)\b/i;
28
- const CTX_SIGNATURE_HINT =
29
- "Hint: swarm scripts export default async function (args, ctx) — args comes first, ctx second.";
30
-
31
24
  function buildStructuredError(err: unknown, userModulePath: string): StructuredError {
32
25
  const errObj = err instanceof Error ? err : new Error(String(err));
33
26
  const name = errObj.name || "Error";
@@ -57,10 +50,7 @@ function buildStructuredError(err: unknown, userModulePath: string): StructuredE
57
50
  }
58
51
  }
59
52
 
60
- const ctxSignatureHint =
61
- CTX_UNDEFINED_ACCESS_RE.test(message) && CTX_MEMBER_RE.test(message)
62
- ? CTX_SIGNATURE_HINT
63
- : undefined;
53
+ const ctxSignatureHint = ctxSignatureHintFor(message);
64
54
 
65
55
  return {
66
56
  name,
@@ -0,0 +1,152 @@
1
+ import { SourceMapReader } from "./sourcemap";
2
+
3
+ /**
4
+ * Bundles a user script for the quickjs executor. QuickJS runs plain
5
+ * JavaScript only, so Bun strips the types and inlines the imports into one
6
+ * IIFE. The bundle sets `globalThis.__swarm_module` to the module namespace.
7
+ *
8
+ * Bare imports:
9
+ * - `zod` is inlined from its ESM sources, so Bun tree-shakes it. Each run
10
+ * evaluates only the zod code that the script uses.
11
+ * - `stdlib` and `swarm-sdk` resolve to small virtual modules that read the
12
+ * sandbox globals the quickjs runner installs.
13
+ */
14
+
15
+ export const USER_SCRIPT_FILE = "user-script.ts";
16
+ const VIRTUAL_DIR = "/swarm-virtual";
17
+ const ENTRY_PATH = `${VIRTUAL_DIR}/entry.ts`;
18
+ const USER_PATH = `${VIRTUAL_DIR}/${USER_SCRIPT_FILE}`;
19
+
20
+ const STDLIB_MODULE = `const s = globalThis.__swarm_stdlib;
21
+ export const fetch = s.fetch;
22
+ export const fetchJson = s.fetchJson;
23
+ export const glob = s.glob;
24
+ export const grep = s.grep;
25
+ export const table = s.table;
26
+ export const Redacted = s.Redacted;
27
+ `;
28
+
29
+ const SWARM_SDK_MODULE = `export function createSwarmSdk() {
30
+ return globalThis.__swarm_ctx.swarm;
31
+ }
32
+ `;
33
+
34
+ export type QuickJSBundle =
35
+ | { ok: true; code: string; map: SourceMapReader | undefined }
36
+ | { ok: false; diagnostic: string };
37
+
38
+ type BuildConfigWithFiles = Parameters<typeof Bun.build>[0] & { files: Record<string, string> };
39
+
40
+ let zodEntryCache: string | null | undefined;
41
+
42
+ /**
43
+ * Prefer zod's real ESM sources, which tree-shake well. The prebuilt
44
+ * `zod.bundle.js` of the API image barely tree-shakes (~340 KB against ~87 KB
45
+ * for z.object + z.string().email()), so it is only the last fallback.
46
+ */
47
+ export async function resolveZodEntry(): Promise<string | null> {
48
+ if (zodEntryCache !== undefined) return zodEntryCache;
49
+ const runtimeDir = process.env.SCRIPT_RUNTIME_DIR;
50
+ const candidates: Array<() => string | undefined> = [
51
+ () => (runtimeDir ? `${runtimeDir}/zod-esm/index.js` : undefined),
52
+ () => Bun.resolveSync("zod", import.meta.dir),
53
+ () => (runtimeDir ? `${runtimeDir}/zod.bundle.js` : undefined),
54
+ ];
55
+ for (const candidate of candidates) {
56
+ try {
57
+ const path = candidate();
58
+ if (path && (await Bun.file(path).exists())) {
59
+ zodEntryCache = path;
60
+ return path;
61
+ }
62
+ } catch {
63
+ // Try the next candidate. Bun.resolveSync throws inside the compiled binary.
64
+ }
65
+ }
66
+ zodEntryCache = null;
67
+ return null;
68
+ }
69
+
70
+ const CACHE_LIMIT = 128;
71
+ const cache = new Map<string, QuickJSBundle>();
72
+
73
+ function remember(key: string, bundle: QuickJSBundle): QuickJSBundle {
74
+ if (cache.size >= CACHE_LIMIT) {
75
+ const oldest = cache.keys().next().value;
76
+ if (oldest !== undefined) cache.delete(oldest);
77
+ }
78
+ cache.set(key, bundle);
79
+ return bundle;
80
+ }
81
+
82
+ export async function bundleForQuickJS(source: string): Promise<QuickJSBundle> {
83
+ const key = Bun.hash(source).toString(36);
84
+ const cached = cache.get(key);
85
+ if (cached) {
86
+ // Refresh the LRU position.
87
+ cache.delete(key);
88
+ cache.set(key, cached);
89
+ return cached;
90
+ }
91
+
92
+ const zodEntry = await resolveZodEntry();
93
+ let result: Awaited<ReturnType<typeof Bun.build>>;
94
+ try {
95
+ result = await Bun.build({
96
+ entrypoints: [ENTRY_PATH],
97
+ // In-memory sources (Bun >= 1.3). The pinned bun-types predate the option.
98
+ files: {
99
+ [ENTRY_PATH]: `import * as m from "./${USER_SCRIPT_FILE}";\nglobalThis.__swarm_module = m;\n`,
100
+ [USER_PATH]: source,
101
+ },
102
+ format: "iife",
103
+ target: "browser",
104
+ sourcemap: "external",
105
+ // Less source for QuickJS to parse on every run. Identifiers stay, so
106
+ // stack frames keep their function names; the source map keeps lines.
107
+ minify: { whitespace: true, syntax: true, identifiers: false },
108
+ plugins: [
109
+ {
110
+ name: "swarm-script-imports",
111
+ setup(build) {
112
+ build.onResolve({ filter: /^(stdlib|swarm-sdk)$/ }, (args) => ({
113
+ path: args.path,
114
+ namespace: "swarm-virtual",
115
+ }));
116
+ build.onLoad({ filter: /.*/, namespace: "swarm-virtual" }, (args) => ({
117
+ contents: args.path === "stdlib" ? STDLIB_MODULE : SWARM_SDK_MODULE,
118
+ loader: "js",
119
+ }));
120
+ build.onResolve({ filter: /^zod$/ }, () => {
121
+ if (!zodEntry) {
122
+ throw new Error("zod is not available to the quickjs executor in this deployment");
123
+ }
124
+ return { path: zodEntry };
125
+ });
126
+ },
127
+ },
128
+ ],
129
+ } as BuildConfigWithFiles);
130
+ } catch (error) {
131
+ // Bun.build throws an AggregateError for syntax and resolve errors.
132
+ const messages =
133
+ error instanceof AggregateError
134
+ ? error.errors.map((entry) => String(entry?.message ?? entry))
135
+ : [error instanceof Error ? error.message : String(error)];
136
+ return { ok: false, diagnostic: messages.join("\n") };
137
+ }
138
+
139
+ if (!result.success) {
140
+ return {
141
+ ok: false,
142
+ diagnostic: result.logs.map((log) => String(log.message ?? log)).join("\n"),
143
+ };
144
+ }
145
+
146
+ const output = result.outputs.find((artifact) => artifact.kind === "entry-point");
147
+ if (!output) return { ok: false, diagnostic: "quickjs bundle produced no entry point" };
148
+ const code = await output.text();
149
+ const mapArtifact = result.outputs.find((artifact) => artifact.kind === "sourcemap");
150
+ const map = mapArtifact ? new SourceMapReader(JSON.parse(await mapArtifact.text())) : undefined;
151
+ return remember(key, { ok: true, code, map });
152
+ }
@@ -0,0 +1,285 @@
1
+ /**
2
+ * JavaScript that the quickjs runner evaluates inside the sandbox before the
3
+ * user bundle. It rebuilds the script `ctx` (swarm, api, mcp, stdlib, logger)
4
+ * on top of the host functions:
5
+ *
6
+ * - `__host_call(path, argsJson)`: async host call, resolves to a JSON envelope.
7
+ * - `__host_sync(op, json)`: sync host call, returns a JSON envelope.
8
+ * - `__host_log(stream, text)`: append to the captured stdout or stderr.
9
+ * - `__host_sleep(ms)`: resolves after `ms` on the host clock.
10
+ * - `__host_done(json)`: reports the final outcome of the run.
11
+ *
12
+ * Every value crosses the boundary as JSON. The sandbox has no other way out.
13
+ * `__swarm_shape` (injected before this file) lists the configured api/mcp
14
+ * connections so `ctx.api.<slug>` matches the native executor exactly.
15
+ */
16
+ export const SANDBOX_PRELUDE = String.raw`(() => {
17
+ "use strict";
18
+ const shape = globalThis.__swarm_shape;
19
+
20
+ const unwrap = (json) => {
21
+ const envelope = JSON.parse(json);
22
+ if (envelope.error !== undefined) {
23
+ const error = new Error(envelope.error.message);
24
+ if (envelope.error.name) error.name = envelope.error.name;
25
+ throw error;
26
+ }
27
+ return envelope.value;
28
+ };
29
+ const hostCall = async (path, args) =>
30
+ unwrap(await __host_call(path, JSON.stringify(args === undefined ? null : args)));
31
+ const hostSync = (op, value) => unwrap(__host_sync(op, JSON.stringify(value === undefined ? null : value)));
32
+
33
+ // ── console ──
34
+ const format = (value) => {
35
+ if (typeof value === "string") return value;
36
+ if (value instanceof Error) return value.stack ? value.name + ": " + value.message + "\n" + value.stack : String(value);
37
+ try {
38
+ const json = JSON.stringify(value);
39
+ return json === undefined ? String(value) : json;
40
+ } catch {
41
+ return String(value);
42
+ }
43
+ };
44
+ const logTo = (stream) => (...args) => __host_log(stream, args.map(format).join(" ") + "\n");
45
+ const console = {
46
+ log: logTo("stdout"),
47
+ info: logTo("stdout"),
48
+ debug: logTo("stdout"),
49
+ warn: logTo("stderr"),
50
+ error: logTo("stderr"),
51
+ };
52
+
53
+ // ── timers ──
54
+ let timerSeq = 0;
55
+ const timers = new Set();
56
+ const setTimeout = (fn, ms, ...args) => {
57
+ const id = ++timerSeq;
58
+ timers.add(id);
59
+ __host_sleep(Number(ms) || 0).then(() => {
60
+ if (timers.delete(id)) fn(...args);
61
+ });
62
+ return id;
63
+ };
64
+ const clearTimeout = (id) => {
65
+ timers.delete(id);
66
+ };
67
+
68
+ // ── Redacted ──
69
+ const redactedEntries = new WeakMap();
70
+ const redactedProto = Object.freeze({
71
+ toString() {
72
+ return "<redacted>";
73
+ },
74
+ toJSON() {
75
+ return "<redacted>";
76
+ },
77
+ });
78
+ const entryOf = (self) => {
79
+ const entry = redactedEntries.get(self);
80
+ if (!entry) throw new Error("Redacted value was not in registry");
81
+ return entry;
82
+ };
83
+ const hostRedacted = (hostId) => {
84
+ const value = Object.create(redactedProto);
85
+ redactedEntries.set(value, { hostId });
86
+ return value;
87
+ };
88
+ const Redacted = Object.freeze({
89
+ make(value, meta = { type: "user", isSecret: false }) {
90
+ const redacted = Object.create(redactedProto);
91
+ redactedEntries.set(redacted, { value, meta });
92
+ return redacted;
93
+ },
94
+ value(self) {
95
+ const entry = entryOf(self);
96
+ return "hostId" in entry ? hostSync("redacted.value", entry.hostId) : entry.value;
97
+ },
98
+ meta(self) {
99
+ const entry = entryOf(self);
100
+ return "hostId" in entry ? hostSync("redacted.meta", entry.hostId) : entry.meta;
101
+ },
102
+ isSecret(self) {
103
+ return Redacted.meta(self).isSecret;
104
+ },
105
+ });
106
+
107
+ const config = Object.freeze({
108
+ apiKey: hostRedacted("system:apiKey"),
109
+ agentId: hostRedacted("system:agentId"),
110
+ mcpBaseUrl: hostRedacted("system:mcpBaseUrl"),
111
+ runtimeInstanceId: shape.hasRuntimeInstanceId ? hostRedacted("system:runtimeInstanceId") : undefined,
112
+ extensionToken: undefined,
113
+ get(key) {
114
+ return hostSync("config.has", key) ? hostRedacted("user:" + key) : undefined;
115
+ },
116
+ });
117
+
118
+ // ── fetch (text bodies only) ──
119
+ class Headers {
120
+ constructor(init) {
121
+ this._map = new Map();
122
+ const pairs = init == null ? [] : Array.isArray(init) ? init
123
+ : typeof init.entries === "function" ? Array.from(init.entries()) : Object.entries(init);
124
+ for (const [key, value] of pairs) this._map.set(String(key).toLowerCase(), String(value));
125
+ }
126
+ get(key) {
127
+ const value = this._map.get(String(key).toLowerCase());
128
+ return value === undefined ? null : value;
129
+ }
130
+ has(key) {
131
+ return this._map.has(String(key).toLowerCase());
132
+ }
133
+ set(key, value) {
134
+ this._map.set(String(key).toLowerCase(), String(value));
135
+ }
136
+ entries() {
137
+ return this._map.entries();
138
+ }
139
+ keys() {
140
+ return this._map.keys();
141
+ }
142
+ forEach(callback) {
143
+ this._map.forEach((value, key) => callback(value, key, this));
144
+ }
145
+ [Symbol.iterator]() {
146
+ return this._map.entries();
147
+ }
148
+ }
149
+ class Response {
150
+ constructor(raw) {
151
+ this.status = raw.status;
152
+ this.statusText = raw.statusText;
153
+ this.ok = raw.ok;
154
+ this.url = raw.url;
155
+ this.headers = new Headers(raw.headers);
156
+ this._body = raw.body;
157
+ this.bodyUsed = false;
158
+ }
159
+ async text() {
160
+ this.bodyUsed = true;
161
+ return this._body;
162
+ }
163
+ async json() {
164
+ this.bodyUsed = true;
165
+ return JSON.parse(this._body);
166
+ }
167
+ }
168
+ const toRequest = (input, init) => {
169
+ const options = init || {};
170
+ const url = typeof input === "string" ? input : input && (input.href || input.url) ? input.href || input.url : String(input);
171
+ if (options.body != null && typeof options.body !== "string") {
172
+ throw new TypeError("quickjs executor: fetch body must be a string (JSON.stringify it first)");
173
+ }
174
+ const headers = options.headers == null ? undefined : Array.from(new Headers(options.headers).entries());
175
+ const request = { url, method: options.method, headers, body: options.body == null ? undefined : options.body };
176
+ if (options.retries !== undefined) request.retries = options.retries;
177
+ if (options.timeoutMs !== undefined) request.timeoutMs = options.timeoutMs;
178
+ return request;
179
+ };
180
+ const fetch = async (input, init) => new Response(await hostCall("fetch", [toRequest(input, init)]));
181
+
182
+ const unavailable = (name) => () => {
183
+ throw new Error(name + " is not available in the quickjs executor (no filesystem access)");
184
+ };
185
+ const stdlib = Object.freeze({
186
+ fetch: async (input, options) => new Response(await hostCall("stdlib.fetch", [toRequest(input, options)])),
187
+ fetchJson: async (input, options) => hostCall("stdlib.fetchJson", [toRequest(input, options)]),
188
+ glob: unavailable("ctx.stdlib.glob"),
189
+ grep: unavailable("ctx.stdlib.grep"),
190
+ table: (rows) => hostSync("table", rows),
191
+ Redacted,
192
+ });
193
+
194
+ // ── ctx ──
195
+ const method = (path) => (...args) => hostCall(path, args);
196
+ const room = Object.freeze({
197
+ get: method("swarm.room.get"),
198
+ change: method("swarm.room.change"),
199
+ reset: method("swarm.room.reset"),
200
+ decode: method("swarm.room.decode"),
201
+ });
202
+ const swarm = new Proxy({ room, config }, {
203
+ get(target, prop) {
204
+ if (typeof prop !== "string") return undefined;
205
+ if (prop in target) return target[prop];
206
+ if (prop === "then") return undefined;
207
+ return method("swarm." + prop);
208
+ },
209
+ });
210
+ const registry = (kind) => {
211
+ const out = {};
212
+ for (const [slug, names] of Object.entries(shape[kind])) {
213
+ const client = {};
214
+ for (const name of names) client[name] = method(kind + "." + slug + "." + name);
215
+ out[slug] = client;
216
+ }
217
+ return out;
218
+ };
219
+ const ctx = Object.freeze({ swarm, api: registry("api"), mcp: registry("mcp"), stdlib, logger: console });
220
+
221
+ const define = (name, value) =>
222
+ Object.defineProperty(globalThis, name, { value, writable: true, configurable: true, enumerable: false });
223
+ define("console", console);
224
+ define("setTimeout", setTimeout);
225
+ define("clearTimeout", clearTimeout);
226
+ define("fetch", fetch);
227
+ define("Headers", Headers);
228
+ define("Response", Response);
229
+ define("__swarm_stdlib", stdlib);
230
+ define("__swarm_ctx", ctx);
231
+ })();
232
+ `;
233
+
234
+ /**
235
+ * Runs the script's default export with `(args, ctx)` after the optional
236
+ * zod `argsSchema` check, the same contract as `eval-harness.ts`.
237
+ */
238
+ export const SANDBOX_EPILOGUE = String.raw`(async () => {
239
+ const mod = globalThis.__swarm_module;
240
+ if (!mod || typeof mod.default !== "function") {
241
+ throw new Error(
242
+ "Swarm script must export a default function. Script must export default async function (args, ctx): args FIRST, ctx second.",
243
+ );
244
+ }
245
+ let args = globalThis.__swarm_args;
246
+ if (mod.argsSchema && typeof mod.argsSchema === "object" && "parse" in mod.argsSchema) {
247
+ try {
248
+ args = mod.argsSchema.parse(args);
249
+ } catch (error) {
250
+ if (error && typeof error === "object" && Array.isArray(error.issues)) {
251
+ const issues = error.issues
252
+ .map((issue) => " " + (issue.path.length ? issue.path.join(".") : "(root)") + ": " + issue.message)
253
+ .join("\n");
254
+ throw new Error("argsSchema validation failed:\n" + issues);
255
+ }
256
+ throw error;
257
+ }
258
+ }
259
+ return await mod.default(args, globalThis.__swarm_ctx);
260
+ })().then(
261
+ (value) => {
262
+ let json;
263
+ try {
264
+ json = JSON.stringify({ ok: true, result: value === undefined ? null : value });
265
+ } catch (error) {
266
+ json = JSON.stringify({
267
+ ok: false,
268
+ error: { name: "TypeError", message: "Script result is not JSON-serializable: " + error.message, stack: "" },
269
+ });
270
+ }
271
+ __host_done(json);
272
+ },
273
+ (error) =>
274
+ __host_done(
275
+ JSON.stringify({
276
+ ok: false,
277
+ error: {
278
+ name: (error && error.name) || "Error",
279
+ message: error && error.message !== undefined ? String(error.message) : String(error),
280
+ stack: (error && error.stack) || "",
281
+ },
282
+ }),
283
+ ),
284
+ );
285
+ `;