@desplega.ai/agent-swarm 2.6.0 → 2.7.1

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 (324) hide show
  1. package/README.md +2 -0
  2. package/dist/{acp-adapter-dgfakfpw.js → acp-adapter-8dn5tq56.js} +6 -6
  3. package/dist/{actions-fbqma8aa.js → actions-3r6gw7dy.js} +18 -18
  4. package/dist/{amp-adapter-en0jy6hs.js → amp-adapter-wjtq413p.js} +3 -3
  5. package/dist/{anthropic-messages-txs190dd.js → anthropic-messages-n4cby1rz.js} +4 -4
  6. package/dist/{app-k8a5cgpp.js → app-d53yhykk.js} +3 -3
  7. package/dist/{assistant-a16433gr.js → assistant-ksrawj3k.js} +20 -20
  8. package/dist/{boot-reembed-6c1sjfnr.js → boot-reembed-fxfw17m2.js} +11 -3
  9. package/dist/{boot-reembed-f4nn561n.js → boot-reembed-k5y5xbj0.js} +15 -8
  10. package/dist/{boot-scrub-sweep-d4w9gajf.js → boot-scrub-sweep-se41j9fd.js} +3 -3
  11. package/dist/{boot-seeds-9bmkspyw.js → boot-seeds-r3kwwv8b.js} +4 -4
  12. package/dist/{claude-adapter-nys1kjxa.js → claude-adapter-ahmyf231.js} +8 -8
  13. package/dist/{claude-managed-adapter-55207973.js → claude-managed-adapter-5knamegc.js} +3 -3
  14. package/dist/{claude-managed-setup-3cm35gey.js → claude-managed-setup-mdc7dy6b.js} +3 -3
  15. package/dist/{claude-sdk-session-nw5yd8cp.js → claude-sdk-session-n5wen9zk.js} +8729 -8600
  16. package/dist/{cli-683y0b3a.js → cli-0dqtv2jg.js} +2 -2
  17. package/dist/{cli-a34pr3w1.js → cli-0tww7dnz.js} +2 -2
  18. package/dist/{cli-w2656ka1.js → cli-0w4e4v58.js} +7 -7
  19. package/dist/{cli-5sckpqcx.js → cli-2sjm3t4r.js} +1 -1
  20. package/dist/{cli-gf2850q7.js → cli-3cywb44q.js} +18 -1
  21. package/dist/{cli-8wkb09q5.js → cli-3k9jej0c.js} +2 -2
  22. package/dist/{cli-3aqd4jaa.js → cli-3v2cyqb8.js} +3 -3
  23. package/dist/{cli-emhjcj2y.js → cli-5qt9vzmq.js} +89 -20
  24. package/dist/{cli-abkm71vr.js → cli-5rp1w4cr.js} +1 -1
  25. package/dist/{cli-gf95q3bm.js → cli-6vwjsetx.js} +4 -4
  26. package/dist/{cli-k21gx5ht.js → cli-6w2yrrc0.js} +10 -10
  27. package/dist/{cli-m70bajzr.js → cli-75tdydgv.js} +1 -1
  28. package/dist/{cli-5rj83bam.js → cli-8feswf2v.js} +47 -36
  29. package/dist/{cli-sxgtf5fw.js → cli-8wd3mbyj.js} +1 -1
  30. package/dist/{cli-ca6banwz.js → cli-9csfthbw.js} +10 -8
  31. package/dist/{cli-dqygeeh5.js → cli-b41p764a.js} +31 -3
  32. package/dist/{cli-m5a9m0ak.js → cli-c1t533hh.js} +3 -3
  33. package/dist/{cli-2sjhpsns.js → cli-c28jxpcv.js} +1 -1
  34. package/dist/{cli-bqztfyve.js → cli-cb50g9cd.js} +1 -1
  35. package/dist/{cli-ag2yrnt5.js → cli-d8gaphtr.js} +2 -2
  36. package/dist/{cli-9abdgn5t.js → cli-dgtfysne.js} +3 -3
  37. package/dist/{cli-nq677csy.js → cli-dscnhn18.js} +1 -1
  38. package/dist/{cli-3fwqy71j.js → cli-dv11pgpv.js} +39 -32
  39. package/dist/{cli-v49fkghp.js → cli-ekptgk2m.js} +6 -6
  40. package/dist/{cli-c2habvsf.js → cli-f3mzy662.js} +17 -17
  41. package/dist/{cli-zqne1qcj.js → cli-fk7k8s9x.js} +2 -2
  42. package/dist/{cli-1tem6ns9.js → cli-gt4h8cxw.js} +3 -2
  43. package/dist/{cli-vbhgkw9h.js → cli-h3e7bhvn.js} +3 -3
  44. package/dist/{cli-ffvsj2qw.js → cli-hkxqdmnb.js} +3 -3
  45. package/dist/{cli-a2rr0fmg.js → cli-hpkvgdad.js} +7 -4
  46. package/dist/{cli-art7c1zh.js → cli-hq2v4rr5.js} +37 -9
  47. package/dist/{cli-sqma6vw1.js → cli-k1zb7raw.js} +5 -5
  48. package/dist/{cli-4rvr7zfx.js → cli-k4awgvzm.js} +5 -0
  49. package/dist/{cli-3ndmpxxv.js → cli-k7d3hvya.js} +2 -2
  50. package/dist/{cli-3gfvmzht.js → cli-kbtdftbw.js} +74 -26
  51. package/dist/{cli-hfeb68z4.js → cli-kj69b9tw.js} +34 -6
  52. package/dist/{cli-az25fn5f.js → cli-kk9jy4nm.js} +2 -2
  53. package/dist/{cli-39aet655.js → cli-m52t4cta.js} +1 -1
  54. package/dist/{cli-cz37jqss.js → cli-mdadewqp.js} +5 -5
  55. package/dist/{cli-esakngh8.js → cli-nf6k60sn.js} +1 -1
  56. package/dist/{cli-j6rktc91.js → cli-nzdf09js.js} +1 -1
  57. package/dist/{cli-rr7zx19j.js → cli-prcyzecg.js} +12 -12
  58. package/dist/{cli-4hxrf0p4.js → cli-pzafyqtk.js} +393 -62
  59. package/dist/{cli-g8ka5j4j.js → cli-qvaa1gjp.js} +173 -52
  60. package/dist/{cli-d2dpf95n.js → cli-rg4b2g6j.js} +1 -1
  61. package/dist/{cli-kf4jree9.js → cli-rm66vqdz.js} +1 -1
  62. package/dist/{cli-4rf0f5vg.js → cli-s504c3w7.js} +5 -3
  63. package/dist/{cli-nn6vx2mq.js → cli-swkx9jm2.js} +7 -5
  64. package/dist/{cli-g20jjwt4.js → cli-thsaq4pd.js} +16 -16
  65. package/dist/{cli-aj8djyqt.js → cli-twjnyvs8.js} +2 -2
  66. package/dist/{cli-03gg9pd1.js → cli-typdpe8g.js} +4 -4
  67. package/dist/{cli-mtnj4fwa.js → cli-vg8pwmsd.js} +6 -6
  68. package/dist/{cli-gnsb1zxa.js → cli-vhpckzvp.js} +1 -1
  69. package/dist/{cli-7enjwya9.js → cli-vz78s5wm.js} +1 -1
  70. package/dist/{cli-dv97kdzv.js → cli-wdxgsdz5.js} +2 -2
  71. package/dist/{cli-7a6p4e65.js → cli-wtjg6je3.js} +1 -1
  72. package/dist/{cli-6y51ryva.js → cli-x3cngb1h.js} +44 -12
  73. package/dist/{cli-n7asmce6.js → cli-xbz6mcg4.js} +3 -3
  74. package/dist/{cli-24j1jeeb.js → cli-y4tdxsqb.js} +3 -3
  75. package/dist/{cli-mvjz5an3.js → cli-yqrsp3ny.js} +7 -7
  76. package/dist/cli.js +31 -21
  77. package/dist/{codex-adapter-d95q4qsn.js → codex-adapter-7wepzq15.js} +6 -6
  78. package/dist/{codex-hook-brpnycn5.js → codex-hook-pbdh4xhx.js} +2 -2
  79. package/dist/{codex-session-runner-gdwd8h0c.js → codex-session-runner-02sb49e4.js} +6 -6
  80. package/dist/{commands-jqmgk54b.js → commands-3rcspxct.js} +2 -2
  81. package/dist/{controller-z3jq589f.js → controller-8ar4avd6.js} +3 -3
  82. package/dist/{controllers-connect-r2za39ef.js → controllers-connect-ajvh9h0v.js} +19 -19
  83. package/dist/{cursor-adapter-4mr4jgkw.js → cursor-adapter-gd0sa7bh.js} +1 -1
  84. package/dist/{db-w36wwb5g.js → db-dv9j7ts5.js} +2 -2
  85. package/dist/{db-ppv2tze7.js → db-z26vgdvj.js} +3 -3
  86. package/dist/{dispatcher-pv5h77vf.js → dispatcher-8m0htjq8.js} +17 -17
  87. package/dist/{dsh-adapter-d4pdpb3r.js → dsh-adapter-y8gyk130.js} +1 -1
  88. package/dist/{e2b-fn3zacvt.js → e2b-74vg9b7e.js} +1 -1
  89. package/dist/{e2b-222hsajc.js → e2b-jyay8wzn.js} +1 -1
  90. package/dist/{easter-egg-3d-4sp4dvmc.js → easter-egg-3d-28f880xx.js} +1 -1
  91. package/dist/{execute-jev839y1.js → execute-9seb79vh.js} +1 -1
  92. package/dist/{external-channel-y6nkzhnn.js → external-channel-smz7jyth.js} +2 -2
  93. package/dist/{getMachineId-bsd-brn0xym3.js → getMachineId-bsd-whfre6gr.js} +3 -3
  94. package/dist/{getMachineId-darwin-t339sfxm.js → getMachineId-darwin-5zjynb19.js} +3 -3
  95. package/dist/{getMachineId-linux-5eq95d8b.js → getMachineId-linux-8mksrrsq.js} +3 -3
  96. package/dist/{getMachineId-unsupported-qavrtc7j.js → getMachineId-unsupported-fxtqsdt2.js} +3 -3
  97. package/dist/{getMachineId-win-q7fe1wx7.js → getMachineId-win-nzfmz857.js} +3 -3
  98. package/dist/{grok-adapter-t08b9ntm.js → grok-adapter-z0nnvtbn.js} +7 -7
  99. package/dist/handlers-pspryh6g.js +41 -0
  100. package/dist/{heartbeat-vn31xwdk.js → heartbeat-f928aqyp.js} +20 -20
  101. package/dist/{hook-cpjs8q51.js → hook-d7c605r4.js} +7 -7
  102. package/dist/{hook-6d0zbvvt.js → hook-q9hv5xf9.js} +5 -5
  103. package/dist/{http-9c6medda.js → http-q6j4k989.js} +1000 -251
  104. package/dist/{index-k0yt1tvq.js → index-5nb266jr.js} +17 -17
  105. package/dist/{index-ysd45kgc.js → index-8fxt5eah.js} +10 -10
  106. package/dist/{index-zgvqzjsw.js → index-cekzwhez.js} +5 -5
  107. package/dist/{index-38t35h0n.js → index-ch0c1xff.js} +17 -17
  108. package/dist/{index-pkma1yf8.js → index-ebnjhxh1.js} +1 -1
  109. package/dist/{index-yqgbfgaj.js → index-ed8dy8rn.js} +20 -20
  110. package/dist/{index-qhjf2htm.js → index-ejqdkkqx.js} +262 -96
  111. package/dist/{index-dr94zbnh.js → index-farm1zsn.js} +32661 -29443
  112. package/dist/{index-g6k9tctj.js → index-yn1yxg85.js} +1 -1
  113. package/dist/{keepalive-em0117bp.js → keepalive-zzc3hks1.js} +3 -3
  114. package/dist/lead-c0pjcaw4.js +79 -0
  115. package/dist/{maintenance-kbme3qy9.js → maintenance-kqsxzpzx.js} +1 -1
  116. package/dist/{oauth-refresh-sweep-xysj4yse.js → oauth-refresh-sweep-7qt0g55z.js} +8 -3
  117. package/dist/{onboard-p6q0vz97.js → onboard-k7x13fqg.js} +121 -8
  118. package/dist/{opencode-adapter-esv3k9yn.js → opencode-adapter-tqvrtter.js} +5 -5
  119. package/dist/{otel-impl-54qhqh1z.js → otel-impl-sqkf6k3b.js} +97 -97
  120. package/dist/{pi-mono-adapter-mymbwhj0.js → pi-mono-adapter-m2qnafxm.js} +89 -14
  121. package/dist/{pricing-refresh-yb75wv33.js → pricing-refresh-wkpwhgvs.js} +3 -3
  122. package/dist/{rbac-roles-dexhc9x8.js → rbac-roles-dpn0c0wj.js} +7 -4
  123. package/dist/{rbac-roles-1vp2mw4p.js → rbac-roles-wk7xd6a6.js} +2 -2
  124. package/dist/{render-v2-tjay5hhf.js → render-v2-ex2m4g2k.js} +3 -3
  125. package/dist/{resume-8ayf37g5.js → resume-725g9b0b.js} +7 -7
  126. package/dist/{runtime-hqe5cqcd.js → runtime-kajas15g.js} +1 -1
  127. package/dist/{session-access-fdhp987s.js → session-access-0j2ezjje.js} +8 -4
  128. package/dist/{session-source-backfill-qgtc86z1.js → session-source-backfill-62202awe.js} +2 -2
  129. package/dist/{setup-4rrmqcq3.js → setup-9sj11ax6.js} +1 -1
  130. package/dist/{virtual-modules-52km00d6.js → virtual-modules-c6fcq6zr.js} +2 -2
  131. package/dist/{work-objects-p28fgd70.js → work-objects-0y07495y.js} +20 -20
  132. package/dist/worker-d4q9sqbc.js +79 -0
  133. package/openapi.json +1536 -407
  134. package/package.json +7 -5
  135. package/src/be/automation-preflight.ts +2 -0
  136. package/src/be/connector-codes.ts +65 -22
  137. package/src/be/db/api-keys.ts +9 -0
  138. package/src/be/db/workflow-runs.ts +36 -5
  139. package/src/be/db.ts +80 -22
  140. package/src/be/memory/boot-reembed.ts +4 -1
  141. package/src/be/memory/constants.ts +6 -0
  142. package/src/be/memory/embedding-recovery.ts +48 -0
  143. package/src/be/memory/index-content.ts +5 -2
  144. package/src/be/memory/providers/openai-embedding.ts +65 -14
  145. package/src/be/memory/task-learning.ts +257 -0
  146. package/src/be/memory/types.ts +13 -2
  147. package/src/be/migrations/245_script_executor.sql +3 -0
  148. package/src/be/migrations/246_connector_code_kind.sql +11 -0
  149. package/src/be/oauth-refresh-sweep.ts +2 -1
  150. package/src/be/onboarding.ts +125 -15
  151. package/src/be/rbac-roles.ts +4 -1
  152. package/src/be/scripts/boot-reembed.ts +2 -0
  153. package/src/be/scripts/db.ts +14 -4
  154. package/src/be/scripts/embeddings.ts +4 -2
  155. package/src/be/scripts/run-saved.ts +1 -0
  156. package/src/be/scripts/typecheck.ts +9 -3
  157. package/src/be/seed/agent-fs-provision.ts +75 -14
  158. package/src/be/seed-skills/index.ts +7 -0
  159. package/src/be/swarm-config-guard.ts +3 -0
  160. package/src/cli.tsx +9 -0
  161. package/src/comb/config.ts +6 -1
  162. package/src/commands/onboard/agent-fs-version.ts +5 -0
  163. package/src/commands/onboard/compose-generator.ts +117 -4
  164. package/src/commands/onboard/env-generator.ts +9 -0
  165. package/src/commands/onboard/tei-image.ts +12 -0
  166. package/src/commands/onboard/types.ts +7 -0
  167. package/src/commands/onboard.tsx +11 -1
  168. package/src/commands/provider-credentials.ts +2 -1
  169. package/src/commands/runner.ts +14 -1
  170. package/src/heartbeat/heartbeat.ts +14 -1
  171. package/src/heartbeat/script-runner-probe.ts +47 -0
  172. package/src/http/agentfs-proxy.ts +369 -0
  173. package/src/http/all-routes.ts +1 -0
  174. package/src/http/api-keys.ts +24 -9
  175. package/src/http/codex-oauth-device.ts +8 -1
  176. package/src/http/fs.ts +64 -10
  177. package/src/http/idempotency-key.ts +1 -1
  178. package/src/http/inbox-state.ts +27 -1
  179. package/src/http/index.ts +7 -4
  180. package/src/http/memory.ts +7 -4
  181. package/src/http/onboarding.ts +139 -11
  182. package/src/http/pages-public.ts +38 -5
  183. package/src/http/scripts.ts +27 -0
  184. package/src/http/session-access.ts +24 -0
  185. package/src/http/sessions.ts +10 -6
  186. package/src/http/tasks.ts +85 -11
  187. package/src/http/telemetry-ui.ts +1 -1
  188. package/src/http/user-roles.ts +4 -1
  189. package/src/http/users.ts +272 -3
  190. package/src/http/utils.ts +22 -3
  191. package/src/http/workflows.ts +10 -0
  192. package/src/http/x.ts +5 -0
  193. package/src/prompts/base-prompt.ts +45 -10
  194. package/src/prompts/session-templates.ts +43 -5
  195. package/src/providers/amp-adapter.ts +1 -1
  196. package/src/providers/codex-adapter.ts +6 -1
  197. package/src/providers/cursor-adapter.ts +1 -1
  198. package/src/providers/dsh-adapter.ts +1 -1
  199. package/src/providers/pi-mono-adapter.ts +99 -14
  200. package/src/rbac/legacy-policy.ts +1 -0
  201. package/src/rbac/permissions.ts +4 -0
  202. package/src/scheduler/scheduler.ts +2 -1
  203. package/src/scripts-runtime/eval-harness.ts +8 -1
  204. package/src/scripts-runtime/executors/native.ts +22 -16
  205. package/src/scripts-runtime/executors/quickjs-prelude.ts +103 -1
  206. package/src/scripts-runtime/executors/quickjs-runner.ts +2 -1
  207. package/src/scripts-runtime/executors/quickjs.ts +7 -0
  208. package/src/scripts-runtime/executors/registry.ts +32 -0
  209. package/src/scripts-runtime/executors/types.ts +7 -0
  210. package/src/scripts-runtime/host-validated-args.ts +133 -0
  211. package/src/scripts-runtime/loader.ts +30 -3
  212. package/src/scripts-runtime/swarm-sdk.ts +9 -2
  213. package/src/scripts-runtime/types/stdlib.d.ts +9 -1
  214. package/src/scripts-runtime/types/swarm-sdk.d.ts +9 -1
  215. package/src/tests/agent-fs-provision-seeder.test.ts +261 -92
  216. package/src/tests/agentfs-proxy.test.ts +1106 -0
  217. package/src/tests/api-key-status-by-suffix.test.ts +242 -0
  218. package/src/tests/base-prompt.test.ts +139 -4
  219. package/src/tests/codex-adapter.test.ts +46 -8
  220. package/src/tests/codex-oauth-device.test.ts +12 -1
  221. package/src/tests/comb-config-guard.test.ts +20 -0
  222. package/src/tests/comb-links.test.ts +79 -1
  223. package/src/tests/comb-status.test.ts +44 -0
  224. package/src/tests/community-linear-delivery-loop.test.ts +2099 -0
  225. package/src/tests/credential-check.test.ts +4 -2
  226. package/src/tests/docs-index-footprint.test.js +3 -3
  227. package/src/tests/docs-index.test.ts +135 -0
  228. package/src/tests/dsh-adapter.test.ts +1 -1
  229. package/src/tests/fetch-resolved-env.test.ts +16 -2
  230. package/src/tests/fixtures/onboard/baseline-states.ts +68 -0
  231. package/src/tests/fixtures/onboard/content.compose.yml.txt +190 -0
  232. package/src/tests/fixtures/onboard/content.env.txt +29 -0
  233. package/src/tests/fixtures/onboard/dev.compose.yml.txt +155 -0
  234. package/src/tests/fixtures/onboard/dev.env.txt +28 -0
  235. package/src/tests/fixtures/onboard/full-all.compose.yml.txt +582 -0
  236. package/src/tests/fixtures/onboard/full-all.env.txt +59 -0
  237. package/src/tests/fixtures/onboard/full.compose.yml.txt +435 -0
  238. package/src/tests/fixtures/onboard/full.env.txt +36 -0
  239. package/src/tests/fixtures/onboard/research.compose.yml.txt +155 -0
  240. package/src/tests/fixtures/onboard/research.env.txt +28 -0
  241. package/src/tests/fixtures/onboard/solo.compose.yml.txt +85 -0
  242. package/src/tests/fixtures/onboard/solo.env.txt +26 -0
  243. package/src/tests/heartbeat-checklist.test.ts +89 -0
  244. package/src/tests/heartbeat-script-runner-probe.test.ts +83 -0
  245. package/src/tests/http-log-scrubbing.test.ts +34 -1
  246. package/src/tests/http-task-write-ownership.test.ts +5 -1
  247. package/src/tests/invites-http.test.ts +464 -0
  248. package/src/tests/memory-embedding-input-cap.test.ts +122 -1
  249. package/src/tests/memory-embedding-recovery.test.ts +137 -0
  250. package/src/tests/oauth-refresh-sweep.test.ts +34 -1
  251. package/src/tests/onboard-compose.test.ts +162 -0
  252. package/src/tests/onboard-env.test.ts +24 -0
  253. package/src/tests/onboard-non-interactive.test.ts +29 -0
  254. package/src/tests/onboard-tei-image.test.ts +36 -0
  255. package/src/tests/onboarding.test.ts +451 -4
  256. package/src/tests/openai-embedding-provider.test.ts +105 -2
  257. package/src/tests/opencode-adapter.test.ts +2 -1
  258. package/src/tests/pages-frame-ancestors.test.ts +162 -0
  259. package/src/tests/pi-codemode.test.ts +2 -1
  260. package/src/tests/pi-mono-adapter.test.ts +54 -0
  261. package/src/tests/pi-mono-session-cost-on-abort.test.ts +270 -0
  262. package/src/tests/pi-native-mcp.test.ts +13 -1
  263. package/src/tests/pi-tool-exposure.test.ts +8 -8
  264. package/src/tests/preload-env.test.ts +4 -0
  265. package/src/tests/preload.ts +4 -0
  266. package/src/tests/probe-tool-schema-tokens.test.ts +144 -0
  267. package/src/tests/prompt-template-session.test.ts +20 -3
  268. package/src/tests/rbac-admission-e2e.test.ts +22 -6
  269. package/src/tests/rbac-admission.test.ts +342 -4
  270. package/src/tests/rbac-engine.test.ts +1 -0
  271. package/src/tests/rbac-roles.test.ts +9 -1
  272. package/src/tests/request-composition-derive.test.ts +329 -0
  273. package/src/tests/script-connections.test.ts +2 -0
  274. package/src/tests/script-executor-conformance.test.ts +36 -1
  275. package/src/tests/script-executor-quickjs-pool.test.ts +50 -0
  276. package/src/tests/script-executor-quickjs.test.ts +140 -0
  277. package/src/tests/script-host-validated-args-native.test.ts +196 -0
  278. package/src/tests/script-per-script-executor.test.ts +415 -0
  279. package/src/tests/scripts-external-api.test.ts +45 -0
  280. package/src/tests/sdk-allowlist.test.ts +3 -2
  281. package/src/tests/self-improvement.test.ts +4 -4
  282. package/src/tests/send-task-requester-gate.test.ts +64 -3
  283. package/src/tests/sessions-move.test.ts +39 -1
  284. package/src/tests/store-progress-learning.test.ts +381 -0
  285. package/src/tests/ui-logs-parser.test.ts +180 -0
  286. package/src/tests/whoami-route.test.ts +41 -0
  287. package/src/tests/workflow-engine-v2.test.ts +116 -1
  288. package/src/tests/workflow-mcp-trigger-schema.test.ts +209 -0
  289. package/src/tests/workflow-run-finished-event.test.ts +263 -0
  290. package/src/tests/workflow-swarm-script.test.ts +34 -0
  291. package/src/tools/inject-learning.ts +1 -1
  292. package/src/tools/memory-edit.ts +1 -1
  293. package/src/tools/memory-search.ts +1 -1
  294. package/src/tools/script-common.ts +1 -0
  295. package/src/tools/script-run.ts +7 -0
  296. package/src/tools/script-upsert.ts +7 -0
  297. package/src/tools/store-progress.ts +71 -1
  298. package/src/tools/utils.ts +12 -1
  299. package/src/tools/workflows/trigger-workflow.ts +104 -10
  300. package/src/types.ts +12 -1
  301. package/src/utils/constants.ts +39 -0
  302. package/src/utils/credentials.ts +5 -2
  303. package/src/utils/task-attachment-links.ts +15 -3
  304. package/src/workflows/engine.ts +18 -16
  305. package/src/workflows/executors/swarm-script.ts +5 -0
  306. package/src/workflows/foreach-driver.ts +5 -11
  307. package/src/workflows/node-timeout.ts +30 -0
  308. package/templates/community/linear-delivery-loop/PLAYBOOK.md +323 -0
  309. package/templates/community/linear-delivery-loop/README.md +38 -0
  310. package/templates/community/linear-delivery-loop/config.example.json +31 -0
  311. package/templates/community/linear-delivery-loop/lead-prompt.md +34 -0
  312. package/templates/community/linear-delivery-loop/schedule.json +10 -0
  313. package/templates/community/linear-delivery-loop/scripts/linear-delivery-setup.ts +148 -0
  314. package/templates/community/linear-delivery-loop/scripts/linear-delivery-tick.ts +1781 -0
  315. package/templates/skills/swarm-docs/config.json +14 -0
  316. package/templates/skills/swarm-docs/content.md +144 -0
  317. package/dist/handlers-eqsnmv95.js +0 -41
  318. package/dist/lead-23e7z59t.js +0 -79
  319. package/dist/worker-e3w7vye1.js +0 -79
  320. package/dist/{azure-openai-responses-9kfwhmn7.js → azure-openai-responses-43asa23s.js} +0 -0
  321. package/dist/{node-vxx896fa.js → node-t28cc56b.js} +0 -0
  322. package/dist/{openai-codex-responses-79s8xnbh.js → openai-codex-responses-jhr3sjtm.js} +3 -3
  323. package/dist/{openai-completions-tdbyts0x.js → openai-completions-gs6yn37k.js} +3 -3
  324. /package/dist/{openai-responses-dm3t5vqp.js → openai-responses-jqm9vwwk.js} +0 -0
@@ -40,12 +40,14 @@ import {
40
40
  typecheckScript,
41
41
  } from "../be/scripts/typecheck";
42
42
  import { can } from "../rbac";
43
+ import { isExecutorAllowedByDeployment } from "../scripts-runtime/executors/registry";
43
44
  import { extractScriptSignature, type ScriptSignature } from "../scripts-runtime/extract-signature";
44
45
  import { checkQuickJSCompat, quickJSCompatWarnings } from "../scripts-runtime/quickjs-compat";
45
46
  import {
46
47
  ScriptApiAuthModeSchema,
47
48
  ScriptApiRecordSchema,
48
49
  type ScriptDetail,
50
+ ScriptExecutorNameSchema,
49
51
  ScriptFsModeSchema,
50
52
  type ScriptListItem,
51
53
  type ScriptRecord,
@@ -67,6 +69,7 @@ const upsertBodySchema = z.object({
67
69
  intent: z.string().default(""),
68
70
  scope: ScriptScopeSchema.default("agent"),
69
71
  fsMode: ScriptFsModeSchema.default("none"),
72
+ executor: ScriptExecutorNameSchema.nullable().optional(),
70
73
  });
71
74
 
72
75
  const runBodySchema = z
@@ -77,6 +80,7 @@ const runBodySchema = z
77
80
  intent: z.string().default(""),
78
81
  scope: ScriptScopeSchema.optional(),
79
82
  fsMode: ScriptFsModeSchema.default("none"),
83
+ executor: ScriptExecutorNameSchema.nullable().optional(),
80
84
  idempotencyKey: z.string().max(200).optional(),
81
85
  })
82
86
  .refine((body) => Boolean(body.name) !== Boolean(body.source), {
@@ -671,6 +675,15 @@ export async function handleScripts(
671
675
  }
672
676
  }
673
677
 
678
+ if (parsed.body.executor && !isExecutorAllowedByDeployment(parsed.body.executor)) {
679
+ jsonError(
680
+ res,
681
+ 'Executor "native" is not permitted when deployment SCRIPT_EXECUTOR="quickjs"',
682
+ 400,
683
+ );
684
+ return true;
685
+ }
686
+
674
687
  const secretRefusal = refuseSourceWithSecrets(parsed.body.source);
675
688
  if (secretRefusal) {
676
689
  json(res, secretRefusal, 400);
@@ -708,6 +721,7 @@ export async function handleScripts(
708
721
  signatureJson: signatureJsonFor(parsed.body.source),
709
722
  argsJsonSchema,
710
723
  fsMode: parsed.body.fsMode,
724
+ executor: parsed.body.executor,
711
725
  agentId: agent.id,
712
726
  isScratch: false,
713
727
  typeChecked: true,
@@ -758,6 +772,7 @@ export async function handleScripts(
758
772
 
759
773
  let source = parsed.body.source;
760
774
  let fsMode = parsed.body.fsMode;
775
+ let executor = parsed.body.executor ?? null;
761
776
  let namedScript: ScriptRecord | null = null;
762
777
  if (parsed.body.name) {
763
778
  const script = await resolveScript(parsed.body.name, agent.id, parsed.body.scope);
@@ -768,6 +783,7 @@ export async function handleScripts(
768
783
  namedScript = script;
769
784
  source = script.source;
770
785
  fsMode = script.fsMode;
786
+ executor = parsed.body.executor !== undefined ? parsed.body.executor : script.executor;
771
787
  }
772
788
 
773
789
  if (fsMode === "workspace-rw") {
@@ -775,6 +791,15 @@ export async function handleScripts(
775
791
  return true;
776
792
  }
777
793
 
794
+ if (executor && !isExecutorAllowedByDeployment(executor)) {
795
+ jsonError(
796
+ res,
797
+ 'Executor "native" is not permitted when deployment SCRIPT_EXECUTOR="quickjs"',
798
+ 400,
799
+ );
800
+ return true;
801
+ }
802
+
778
803
  const startedAt = new Date().toISOString();
779
804
  // Touch before executing so an already-stale scratch script isn't reaped
780
805
  // by the retention sweep while this run is still in flight.
@@ -786,6 +811,7 @@ export async function handleScripts(
786
811
  source: source as string,
787
812
  args: parsed.body.args,
788
813
  fsMode,
814
+ executor,
789
815
  agentId: agent.id,
790
816
  runtimeInstanceId,
791
817
  egressSecrets: credentials.egressSecrets,
@@ -954,6 +980,7 @@ export async function handleScripts(
954
980
  isScratch: script.isScratch,
955
981
  typeChecked: script.typeChecked,
956
982
  fsMode: script.fsMode,
983
+ executor: script.executor,
957
984
  createdByAgentId: script.createdByAgentId,
958
985
  createdAt: script.createdAt,
959
986
  updatedAt: script.updatedAt,
@@ -88,6 +88,30 @@ export async function hasSessionWrite(
88
88
  return hasSessionAccess(access, "write");
89
89
  }
90
90
 
91
+ export const NOT_YOUR_TASK_DENIED =
92
+ "You can only change tasks you requested, or sessions shared with you to edit.";
93
+
94
+ /**
95
+ * True when a user token without a grant-all role (RBAC on) changes a task it
96
+ * does not own: neither the task nor its session root names the user as
97
+ * requester, and the session is not shared with the user for writing. The
98
+ * session wall reads an ownerless root (Slack, schedules, operator key) as
99
+ * everyone's; for such a user it is not theirs to change. Operator, agent and
100
+ * admin callers are never denied here.
101
+ */
102
+ export async function deniesNonOwnerTaskWrite(
103
+ req: IncomingMessage,
104
+ task: { id: string; requestedByUserId?: string | null },
105
+ ): Promise<boolean> {
106
+ const auth = getRequestAuth(req);
107
+ if (auth?.kind !== "user" || !isRbacEnabled()) return false;
108
+ if (task.requestedByUserId === auth.userId) return false;
109
+ if ((await getUserGrant(auth.userId)).grantsAll) return false;
110
+ const root = await getSessionRoot(task.id);
111
+ if (!root?.requestedByUserId) return true;
112
+ return !hasSessionAccess(await sessionAccessForRoot(auth.userId, root), "write");
113
+ }
114
+
91
115
  /**
92
116
  * The parent gate shared by `POST /api/tasks` and `POST /api/apps/{id}/actions/{name}`.
93
117
  * The child inherits the parent's thread context, so an agent caller must own or
@@ -77,7 +77,13 @@ import { isRuntimePoolsEnabled } from "../utils/runtime-pools-flag";
77
77
  import { canMutateTaskNamespace } from "./assets";
78
78
  import { agentFirstPrincipal } from "./request-principal";
79
79
  import { route } from "./route-def";
80
- import { resolveSessionActor, type SessionActor, sessionAccessFor } from "./session-access";
80
+ import {
81
+ deniesNonOwnerTaskWrite,
82
+ NOT_YOUR_TASK_DENIED,
83
+ resolveSessionActor,
84
+ type SessionActor,
85
+ sessionAccessFor,
86
+ } from "./session-access";
81
87
  import { jsonError } from "./utils";
82
88
 
83
89
  // ─── Response Schemas ────────────────────────────────────────────────────────
@@ -660,7 +666,7 @@ const triageSessionListRoute = route({
660
666
  401: { description: "Unauthorized" },
661
667
  },
662
668
  auth: { apiKey: true },
663
- rbac: { ungated: "per-user inbox UI state, same posture as PATCH /api/inbox-state" },
669
+ rbac: { permission: "favorite.write.own" },
664
670
  });
665
671
 
666
672
  const SESSION_MOVE_LIMIT = 200;
@@ -671,10 +677,7 @@ const SessionMoveResultSchema = z.object({
671
677
  moved: z.array(z.string()),
672
678
  skipped: z.array(z.object({ rootTaskId: z.string(), reason: z.string() })),
673
679
  });
674
- const sessionMoveRbac = {
675
- ungated:
676
- "per-session access, per-task task.fs.mutate, and asset-key write checks in the handler, as PATCH /api/assets/task/{id}/key",
677
- };
680
+ const sessionMoveRbac = { permission: "task.fs.mutate" } as const;
678
681
  const sessionMoveResponses = {
679
682
  400: { description: "Invalid namespace or request" },
680
683
  403: { description: "Personal destination not authorized" },
@@ -759,6 +762,7 @@ async function checkSessionMove(
759
762
  const access = await sessionAccessFor(actor, root.id);
760
763
  if (access === "none") return { reason: SESSION_MOVE_UNAVAILABLE };
761
764
  if (!hasSessionAccess(access, "write")) return { reason: "Session write access required" };
765
+ if (await deniesNonOwnerTaskWrite(req, root)) return { reason: NOT_YOUR_TASK_DENIED };
762
766
  }
763
767
  if (root.parentTaskId) return { reason: "Task is not a session root" };
764
768
  const sourceError = sourceMoveError(options.destination ?? null, root);
package/src/http/tasks.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  getAgentById,
12
12
  getAllTasks,
13
13
  getDbClient,
14
+ getInProgressTasksByContextKey,
14
15
  getLeadAgent,
15
16
  getLogsByTaskId,
16
17
  getPausedTasksForAgent,
@@ -39,6 +40,7 @@ import {
39
40
  } from "../be/db";
40
41
  import { modelProfileRefError, taskProfileError } from "../be/db/model-profiles";
41
42
  import { explicitModelErrorForAgent } from "../be/model-validation";
43
+ import { getUserGrant } from "../be/rbac-roles";
42
44
  import { hasSessionAccess, type SessionAccess } from "../be/session-shares";
43
45
  import {
44
46
  getTaskSteeringFields,
@@ -49,7 +51,7 @@ import {
49
51
  } from "../be/steering";
50
52
  import { getTaskCitations, TaskCitationSchema } from "../be/task-citations";
51
53
  import { findUserById } from "../be/users";
52
- import { can, type RbacPrincipal, type RbacResource } from "../rbac";
54
+ import { can, isRbacEnabled, type RbacPrincipal, type RbacResource } from "../rbac";
53
55
  import { chatThreadOfContextKey } from "../tasks/context-key";
54
56
  import { TaskCreationBlockedError } from "../tasks/errors";
55
57
  import { createTaskWithSiblingAwareness } from "../tasks/sibling-awareness";
@@ -87,7 +89,9 @@ import { buildTaskRequestedBy, TaskRequestedBySchema } from "./requested-by";
87
89
  import { bodyTask, route } from "./route-def";
88
90
  import {
89
91
  canReadSession,
92
+ deniesNonOwnerTaskWrite,
90
93
  denyParentAttach,
94
+ NOT_YOUR_TASK_DENIED,
91
95
  readableByFor,
92
96
  resolveSessionActor,
93
97
  SESSION_READ_DENIED,
@@ -279,6 +283,7 @@ const createTask = route({
279
283
  path: "/api/tasks",
280
284
  pattern: ["api", "tasks"],
281
285
  session: bodyTask("parentTaskId"),
286
+ rbac: { permission: "task.create.own" },
282
287
  summary: "Create a new task",
283
288
  tags: ["Tasks"],
284
289
  body: z
@@ -411,6 +416,7 @@ const cancelTaskRoute = route({
411
416
  path: "/api/tasks/{id}/cancel",
412
417
  pattern: ["api", "tasks", null, "cancel"],
413
418
  session: { taskParam: "id" },
419
+ rbac: { permission: "task.cancel.own" },
414
420
  summary: "Cancel a pending or in-progress task",
415
421
  tags: ["Tasks"],
416
422
  params: z.object({ id: z.string() }),
@@ -687,6 +693,7 @@ const pauseTaskRoute = route({
687
693
  path: "/api/tasks/{id}/pause",
688
694
  pattern: ["api", "tasks", null, "pause"],
689
695
  session: { taskParam: "id" },
696
+ rbac: { permission: "task.action.own" },
690
697
  summary: "Pause an in-progress task",
691
698
  tags: ["Tasks"],
692
699
  params: z.object({ id: z.string() }),
@@ -703,6 +710,7 @@ const resumeTaskRoute = route({
703
710
  path: "/api/tasks/{id}/resume",
704
711
  pattern: ["api", "tasks", null, "resume"],
705
712
  session: { taskParam: "id" },
713
+ rbac: { permission: "task.action.own" },
706
714
  summary: "Resume a paused task",
707
715
  tags: ["Tasks"],
708
716
  params: z.object({ id: z.string() }),
@@ -777,9 +785,7 @@ const updateTaskTitleRoute = route({
777
785
  404: { description: "Task not found" },
778
786
  },
779
787
  auth: { apiKey: true },
780
- rbac: {
781
- ungated: "mirrors the pre-RBAC PATCH /api/tasks/{id}/vcs sibling route: bearer auth only",
782
- },
788
+ rbac: { permission: "task.action.own" },
783
789
  });
784
790
 
785
791
  async function canSteerTask(
@@ -879,6 +885,40 @@ async function resolveTaskWritePrincipal(
879
885
  return { kind: "agent", agentId, isLead: agent?.isLead === true };
880
886
  }
881
887
 
888
+ /**
889
+ * May this caller bind a new task to a chat thread? The operator may. An agent needs the
890
+ * lead's chat post permission. A user needs admin, or a role with `integration.chat.post`.
891
+ */
892
+ async function mayBindChatThread(principal: RbacPrincipal): Promise<boolean> {
893
+ if (principal.kind === "operator") return true;
894
+ if (principal.kind === "user") {
895
+ if (!isRbacEnabled()) return true;
896
+ const grant = await getUserGrant(principal.userId);
897
+ return grant.grantsAll || grant.verbs.has("integration.chat.post");
898
+ }
899
+ return can({
900
+ principal,
901
+ verb: "integration.chat.post",
902
+ resource: { kind: "none" },
903
+ source: "http",
904
+ }).allow;
905
+ }
906
+
907
+ /**
908
+ * Sibling awareness copies the open tasks under a contextKey into the new task, and may pick
909
+ * one as its parent. A non-admin user may name a context only when they may write each of
910
+ * its open tasks.
911
+ */
912
+ async function deniesForeignContext(req: IncomingMessage, contextKey: string): Promise<boolean> {
913
+ const auth = getRequestAuth(req);
914
+ if (auth?.kind !== "user" || !isRbacEnabled()) return false;
915
+ if ((await getUserGrant(auth.userId)).grantsAll) return false;
916
+ for (const task of await getInProgressTasksByContextKey(contextKey)) {
917
+ if (await deniesNonOwnerTaskWrite(req, task)) return true;
918
+ }
919
+ return false;
920
+ }
921
+
882
922
  /**
883
923
  * Requester for a new task. Prefer trusted server-side identity: an
884
924
  * authenticated request user, or the caller's own ownership-gated task context
@@ -1070,17 +1110,27 @@ export async function handleTasks(
1070
1110
  return true;
1071
1111
  }
1072
1112
  // A chat-sdk contextKey binds the task to a chat thread that its assignee and creator
1073
- // may then read and post to. An agent may only name a thread other than the parent's
1074
- // with the lead's chat post permission.
1113
+ // may then read and post to. Only a caller with chat post permission may name a thread
1114
+ // other than the parent's.
1075
1115
  if (
1076
- principal.kind === "agent" &&
1077
1116
  parsed.body.contextKey &&
1078
1117
  parsed.body.contextKey !== parentTask?.contextKey &&
1079
1118
  chatThreadOfContextKey(parsed.body.contextKey) &&
1080
- !can({ principal, verb: "integration.chat.post", resource: { kind: "none" }, source: "http" })
1081
- .allow
1119
+ !(await mayBindChatThread(principal))
1082
1120
  ) {
1083
- jsonError(res, "Permission denied: only a lead can bind a task to a chat thread.", 403);
1121
+ jsonError(
1122
+ res,
1123
+ "Permission denied: only a lead or an admin can bind a task to a chat thread.",
1124
+ 403,
1125
+ );
1126
+ return true;
1127
+ }
1128
+ if (
1129
+ parsed.body.contextKey &&
1130
+ parsed.body.contextKey !== parentTask?.contextKey &&
1131
+ (await deniesForeignContext(req, parsed.body.contextKey))
1132
+ ) {
1133
+ jsonError(res, "You don't have access to the tasks in this context.", 403);
1084
1134
  return true;
1085
1135
  }
1086
1136
  let assetKey: string | undefined;
@@ -1240,7 +1290,12 @@ export async function handleTasks(
1240
1290
  return true;
1241
1291
  }
1242
1292
 
1243
- // Humans may cancel any task. Agents get the MCP cancel-task policy:
1293
+ if (await deniesNonOwnerTaskWrite(req, task)) {
1294
+ jsonError(res, NOT_YOUR_TASK_DENIED, 403);
1295
+ return true;
1296
+ }
1297
+
1298
+ // Admins may cancel any task. Agents get the MCP cancel-task policy:
1244
1299
  // lead or task creator.
1245
1300
  const principal = await resolveTaskWritePrincipal(req, myAgentId);
1246
1301
  if (
@@ -1882,6 +1937,11 @@ export async function handleTasks(
1882
1937
  return true;
1883
1938
  }
1884
1939
 
1940
+ if (await deniesNonOwnerTaskWrite(req, task)) {
1941
+ jsonError(res, NOT_YOUR_TASK_DENIED, 403);
1942
+ return true;
1943
+ }
1944
+
1885
1945
  if (myAgentId && task.agentId !== myAgentId) {
1886
1946
  jsonError(res, "Task belongs to another agent", 403);
1887
1947
  return true;
@@ -1945,6 +2005,15 @@ export async function handleTasks(
1945
2005
  if (updateTaskTitleRoute.match(req.method, pathSegments)) {
1946
2006
  const parsed = await updateTaskTitleRoute.parse(req, res, pathSegments, queryParams);
1947
2007
  if (!parsed) return true;
2008
+ const existing = await getTaskById(parsed.params.id);
2009
+ if (!existing) {
2010
+ jsonError(res, "Task not found", 404);
2011
+ return true;
2012
+ }
2013
+ if (await deniesNonOwnerTaskWrite(req, existing)) {
2014
+ jsonError(res, NOT_YOUR_TASK_DENIED, 403);
2015
+ return true;
2016
+ }
1948
2017
  const task = await updateTaskTitle(parsed.params.id, parsed.body.title);
1949
2018
  if (!task) {
1950
2019
  jsonError(res, "Task not found", 404);
@@ -1964,6 +2033,11 @@ export async function handleTasks(
1964
2033
  return true;
1965
2034
  }
1966
2035
 
2036
+ if (await deniesNonOwnerTaskWrite(req, task)) {
2037
+ jsonError(res, NOT_YOUR_TASK_DENIED, 403);
2038
+ return true;
2039
+ }
2040
+
1967
2041
  if (myAgentId && task.agentId !== myAgentId) {
1968
2042
  jsonError(res, "Task belongs to another agent", 403);
1969
2043
  return true;
@@ -32,7 +32,7 @@ const uiEvent = route({
32
32
  401: { description: "Unauthorized" },
33
33
  403: { description: "Guest page sessions cannot send events" },
34
34
  },
35
- rbac: { ungated: "any authenticated dashboard user; event name allowlisted" },
35
+ rbac: { permission: "favorite.write.own" },
36
36
  });
37
37
 
38
38
  const enableTelemetry = route({
@@ -80,7 +80,10 @@ async function composeRoles(userId: string) {
80
80
  }
81
81
 
82
82
  /** Operator or user only; agents never change human roles, even with the shared key. */
83
- async function ensureRoleManager(req: IncomingMessage, res: ServerResponse): Promise<boolean> {
83
+ export async function ensureRoleManager(
84
+ req: IncomingMessage,
85
+ res: ServerResponse,
86
+ ): Promise<boolean> {
84
87
  if (rejectGuest(req, res)) return false;
85
88
  const auth = getRequestAuth(req);
86
89
  if (auth?.kind !== "operator" && auth?.kind !== "user") {