@desplega.ai/agent-swarm 2.3.0 → 2.4.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 (332) hide show
  1. package/README.md +1 -0
  2. package/dist/{acp-adapter-v85a2bqy.js → acp-adapter-zvzr538d.js} +9 -9
  3. package/dist/{actions-zgcxfspj.js → actions-jhtqdw69.js} +21 -19
  4. package/dist/{amp-adapter-jw9xfz42.js → amp-adapter-bd84rhs2.js} +4 -4
  5. package/dist/{app-4e1s4675.js → app-kreq1gwg.js} +3 -3
  6. package/dist/{assistant-v238n9dk.js → assistant-3k22sbsq.js} +23 -21
  7. package/dist/{boot-reembed-p666cw5n.js → boot-reembed-e53x6b9v.js} +1 -1
  8. package/dist/{boot-reembed-w6pm64j4.js → boot-reembed-f6z923ny.js} +1 -1
  9. package/dist/{boot-scrub-sweep-jcyjagn3.js → boot-scrub-sweep-0538vsb7.js} +4 -4
  10. package/dist/{boot-seeds-gbedmamp.js → boot-seeds-6wxqkfk2.js} +4 -4
  11. package/dist/{claude-adapter-q7wspzt8.js → claude-adapter-gfts5044.js} +9 -9
  12. package/dist/{claude-managed-adapter-n7ahjyx6.js → claude-managed-adapter-h2y889ge.js} +3 -3
  13. package/dist/{claude-managed-setup-wza784fb.js → claude-managed-setup-h00hsgtz.js} +2 -2
  14. package/dist/{claude-sdk-session-yf400ptr.js → claude-sdk-session-56besmfz.js} +13 -13
  15. package/dist/{cli-65q70v2v.js → cli-0bh477zn.js} +33 -6
  16. package/dist/{cli-4ync7m60.js → cli-0ebey9hg.js} +1 -1
  17. package/dist/{cli-665j3feb.js → cli-0xk505e8.js} +1 -1
  18. package/dist/{cli-7gh7020n.js → cli-1dmcq2eh.js} +1 -1
  19. package/dist/{cli-gzvb3d4a.js → cli-1jx0srjt.js} +3 -3
  20. package/dist/{cli-zj4d6afs.js → cli-1pa3rz69.js} +21 -6
  21. package/dist/{cli-7ayprxp7.js → cli-2dfbv8qr.js} +8 -0
  22. package/dist/{cli-30m5q8mc.js → cli-3kh4kpqy.js} +6 -6
  23. package/dist/{cli-qrwp40st.js → cli-3p8fqcnh.js} +2 -2
  24. package/dist/{cli-y3dvz6ge.js → cli-3r448dqn.js} +3 -3
  25. package/dist/{cli-a17tzmn0.js → cli-3tnpj2bh.js} +7 -7
  26. package/dist/{cli-ea7chd26.js → cli-471qk6s2.js} +93 -46
  27. package/dist/{cli-a49vpbf3.js → cli-5kqnemen.js} +1 -1
  28. package/dist/{cli-0rh20bp3.js → cli-6ncjvx55.js} +3 -3
  29. package/dist/{cli-fb6t92v8.js → cli-6x9ma5w5.js} +1 -1
  30. package/dist/{cli-k28p6xh7.js → cli-7225gwj7.js} +2 -2
  31. package/dist/{cli-8cvvytad.js → cli-8nyhf7za.js} +3 -3
  32. package/dist/{cli-e09hj50q.js → cli-8wkb09q5.js} +11 -11
  33. package/dist/{cli-j0v75y13.js → cli-a0kcty51.js} +4 -4
  34. package/dist/{cli-zes4tsbb.js → cli-a4gvwttf.js} +4 -4
  35. package/dist/{cli-jhp7w1fy.js → cli-a5ebc95n.js} +2 -2
  36. package/dist/{cli-5d1m1qca.js → cli-ash6xxk7.js} +2 -2
  37. package/dist/{cli-fp4xbw07.js → cli-axh29tyr.js} +14 -12
  38. package/dist/{cli-p22zdvnt.js → cli-bn0rewsy.js} +3 -3
  39. package/dist/{cli-hz64bcnj.js → cli-bn5kevnf.js} +11 -373
  40. package/dist/{cli-8jtrekpy.js → cli-d2mb5s8a.js} +7 -7
  41. package/dist/{cli-c5sbmw1v.js → cli-d82btycs.js} +94 -15
  42. package/dist/{cli-vjfpshn3.js → cli-ejs3m1sx.js} +1 -1
  43. package/dist/{cli-yv0vgscc.js → cli-fpmsqq59.js} +18 -2
  44. package/dist/cli-fz9kewbh.js +382 -0
  45. package/dist/{cli-4s1kqrqg.js → cli-g0hgtz4p.js} +6 -6
  46. package/dist/{cli-hn3pftj2.js → cli-gf0kfg81.js} +7 -7
  47. package/dist/{cli-d43xqzbe.js → cli-hqhzg1qq.js} +2 -2
  48. package/dist/{cli-azs9bhc5.js → cli-j4rqdf2n.js} +2 -2
  49. package/dist/{cli-wtg6edvd.js → cli-jh0qcrga.js} +1 -1
  50. package/dist/{cli-kqypty34.js → cli-k9z4zd4p.js} +6 -5
  51. package/dist/{cli-jhmjwqcg.js → cli-kmqgmcnb.js} +47 -14
  52. package/dist/{cli-8qsx817b.js → cli-kr2pmfqx.js} +583 -769
  53. package/dist/{cli-4g629sgr.js → cli-m2qgh5sv.js} +20 -1
  54. package/dist/{cli-9e9kjqsj.js → cli-mfe7f7b5.js} +2 -2
  55. package/dist/{cli-x3en6ct3.js → cli-nwyw3zhg.js} +1 -1
  56. package/dist/{cli-6vcyw6v7.js → cli-nx462e4v.js} +5 -3
  57. package/dist/{cli-tr24eeny.js → cli-p0rakbrk.js} +9 -9
  58. package/dist/{cli-4hmaheb6.js → cli-p6argxh9.js} +9 -9
  59. package/dist/{cli-3avfh5az.js → cli-pemywhfq.js} +2 -2
  60. package/dist/{cli-etvn5ej2.js → cli-pnp2j5zg.js} +2 -2
  61. package/dist/{cli-wk8ccrz6.js → cli-pw7v69vp.js} +2 -2
  62. package/dist/{cli-ka01m5rb.js → cli-rdq7tzwm.js} +17 -14
  63. package/dist/{cli-re4wkbzx.js → cli-rqqsfz30.js} +677 -104
  64. package/dist/{cli-xgn4rwyv.js → cli-s48yvzb8.js} +4 -4
  65. package/dist/{cli-zv4vy2b0.js → cli-s95dknxh.js} +1 -1
  66. package/dist/{cli-g6p7c2my.js → cli-sjyetj21.js} +2 -2
  67. package/dist/{cli-rdr166ht.js → cli-smvcw9z5.js} +1 -1
  68. package/dist/{cli-fhvqt2fp.js → cli-sv5gb0yb.js} +1 -1
  69. package/dist/{cli-yv3n83x8.js → cli-syhq378v.js} +2 -2
  70. package/dist/{cli-q1812jbw.js → cli-tbhwrxpt.js} +9 -9
  71. package/dist/{cli-w7z94e6c.js → cli-tx00c0h6.js} +4 -2
  72. package/dist/{cli-dxwh4j32.js → cli-vy0fay6k.js} +46 -37
  73. package/dist/{cli-ptkpaqfy.js → cli-wt645v7q.js} +1 -1
  74. package/dist/{cli-ppapy34w.js → cli-wxbn3yfx.js} +2 -2
  75. package/dist/{cli-cby329ny.js → cli-x5mq1fyq.js} +3 -3
  76. package/dist/{cli-rc3r0bnh.js → cli-xbzvet96.js} +6 -6
  77. package/dist/{cli-4mkvwgzr.js → cli-xf234ws8.js} +1 -1
  78. package/dist/{cli-6p7ddg72.js → cli-xftrvxag.js} +5 -5
  79. package/dist/cli-z071fb95.js +848 -0
  80. package/dist/{cli-1v8w782f.js → cli-z1ew8vbq.js} +14 -7
  81. package/dist/{cli-9td5ss65.js → cli-zfg9enh9.js} +3 -3
  82. package/dist/{cli-yxqag76b.js → cli-zw88zjba.js} +1 -1
  83. package/dist/cli.js +19 -19
  84. package/dist/{codex-adapter-nhjj2veb.js → codex-adapter-p6rmm7vv.js} +6 -6
  85. package/dist/{codex-hook-x6tm6y5m.js → codex-hook-x7nejyrr.js} +8 -5
  86. package/dist/{codex-login-35p4sk85.js → codex-login-m819c41r.js} +1 -1
  87. package/dist/{codex-session-runner-6hggrjbx.js → codex-session-runner-8vd5t9t0.js} +7 -7
  88. package/dist/{commands-mrw1ph2w.js → commands-7ems2p13.js} +2 -2
  89. package/dist/{controller-pt1zam5w.js → controller-m263fg43.js} +4 -4
  90. package/dist/{controllers-connect-ymw5541d.js → controllers-connect-bg33ae53.js} +28 -24
  91. package/dist/{cursor-adapter-cf4zh5x0.js → cursor-adapter-cz6nm6mj.js} +3 -3
  92. package/dist/{db-hy80219q.js → db-w505dwa8.js} +2 -2
  93. package/dist/{db-hhpy6m4x.js → db-ys2rbdft.js} +3 -2
  94. package/dist/{devin-adapter-7egzmt0k.js → devin-adapter-zgqadvnm.js} +1 -1
  95. package/dist/{dispatcher-6pdjtkr1.js → dispatcher-0s0mckqr.js} +20 -18
  96. package/dist/{docker-njavd3fb.js → docker-fkgtr75t.js} +2 -2
  97. package/dist/{dsh-adapter-fbx06re2.js → dsh-adapter-3n3net33.js} +3 -3
  98. package/dist/{e2b-5r6a5jeb.js → e2b-7am6tmq6.js} +2 -2
  99. package/dist/{e2b-pw1nvtmh.js → e2b-thdcxtjd.js} +2 -2
  100. package/dist/{easter-egg-3d-6hg2r942.js → easter-egg-3d-5cgynaja.js} +1 -1
  101. package/dist/{event-bus-101fenkh.js → event-bus-9vpk8gmq.js} +1 -1
  102. package/dist/{execute-bcqc69a5.js → execute-t4e6m3rw.js} +1 -1
  103. package/dist/{external-channel-j6vb6ya1.js → external-channel-5b23fv8z.js} +2 -2
  104. package/dist/{google-generative-ai-phpmwxvg.js → google-generative-ai-bmq8gkf3.js} +1 -1
  105. package/dist/{google-vertex-es9ybgdy.js → google-vertex-b1rvp52s.js} +1 -1
  106. package/dist/{grok-adapter-1193sprp.js → grok-adapter-q9fghe5q.js} +10 -10
  107. package/dist/handlers-mqrym347.js +39 -0
  108. package/dist/{heartbeat-h1w1ktce.js → heartbeat-tww6yx1w.js} +23 -21
  109. package/dist/{hook-ejja4bpe.js → hook-dx0pkvar.js} +16 -9
  110. package/dist/{hook-skrbja18.js → hook-pvmh9b6m.js} +6 -6
  111. package/dist/{http-mzh41mfj.js → http-k2ejbt05.js} +975 -292
  112. package/dist/{index-6rmnn89d.js → index-2z710v4x.js} +10 -10
  113. package/dist/{index-xmmkyx82.js → index-dgz61nff.js} +20 -18
  114. package/dist/{index-wgsw9xcz.js → index-g6tbb6ve.js} +1 -1
  115. package/dist/index-h2ek08d6.js +40 -0
  116. package/dist/index-pqfwh9nn.js +41 -0
  117. package/dist/{index-epr2gnbw.js → index-x5aktmp8.js} +1 -1
  118. package/dist/{index-x0q2a4f9.js → index-ysd45kgc.js} +1 -1
  119. package/dist/{index-g909y089.js → index-zgvqzjsw.js} +8 -8
  120. package/dist/{keepalive-4djvbm2j.js → keepalive-nhvpw10z.js} +4 -4
  121. package/dist/lead-jb6sf69z.js +78 -0
  122. package/dist/{maintenance-f3xhnjsm.js → maintenance-agakc519.js} +1 -1
  123. package/dist/{oauth-refresh-sweep-fpd6x6rw.js → oauth-refresh-sweep-4dcbhtn0.js} +3 -3
  124. package/dist/{onboard-196tjgyn.js → onboard-4n2kwa4v.js} +3 -3
  125. package/dist/{opencode-adapter-eeesgfqk.js → opencode-adapter-3s7ax02e.js} +7 -7
  126. package/dist/{otel-impl-g8fh4c21.js → otel-impl-tfa12080.js} +2 -2
  127. package/dist/{pi-mono-adapter-zasp3ze3.js → pi-mono-adapter-ytp7gz8b.js} +24 -13
  128. package/dist/{pricing-refresh-sdcf5yaz.js → pricing-refresh-3cqx3f3x.js} +3 -3
  129. package/dist/{rbac-roles-bsp5657v.js → rbac-roles-9fae5rnv.js} +5 -3
  130. package/dist/{rbac-roles-2x4g1wb5.js → rbac-roles-y6zbfzve.js} +2 -2
  131. package/dist/{render-v2-0pyb39bb.js → render-v2-emawjvc4.js} +3 -3
  132. package/dist/{resume-a86tkj6r.js → resume-zhgts7h7.js} +10 -8
  133. package/dist/{runtime-ar8310ba.js → runtime-xe3aqy4x.js} +1 -1
  134. package/dist/session-access-cm823e06.js +25 -0
  135. package/dist/{setup-ypbzcapd.js → setup-tkp99w1e.js} +1 -1
  136. package/dist/{virtual-modules-wzk6jf3a.js → virtual-modules-4r3zkc20.js} +2 -2
  137. package/dist/{work-objects-yjp8de12.js → work-objects-f722h263.js} +23 -21
  138. package/dist/worker-p7f336rq.js +78 -0
  139. package/dist/{x-8ewt8gxn.js → x-y45mthwn.js} +2 -2
  140. package/openapi.json +1086 -305
  141. package/package.json +2 -2
  142. package/src/apps/action-caller.ts +6 -0
  143. package/src/apps/action-runner.ts +146 -0
  144. package/src/apps/row-store.ts +4 -2
  145. package/src/apps/script-types.ts +17 -4
  146. package/src/be/db/active-sessions.ts +5 -0
  147. package/src/be/db/session-visibility.ts +29 -0
  148. package/src/be/db/tasks/read.ts +61 -3
  149. package/src/be/db/tasks/write.ts +15 -6
  150. package/src/be/db.ts +106 -37
  151. package/src/be/events.ts +11 -0
  152. package/src/be/fleet-benchmark-stats.ts +10 -5
  153. package/src/be/migrations/230_session_shares.sql +23 -0
  154. package/src/be/models-catalog.ts +4 -0
  155. package/src/be/onboarding.ts +6 -0
  156. package/src/be/rbac-roles.ts +2 -0
  157. package/src/be/scripts/typecheck.ts +13 -0
  158. package/src/be/session-shares.ts +244 -0
  159. package/src/be/swarm-config-guard.ts +33 -3
  160. package/src/be/telemetry-enable.ts +1 -1
  161. package/src/commands/provider-credentials.ts +12 -2
  162. package/src/commands/runner.ts +14 -0
  163. package/src/heartbeat/heartbeat.ts +2 -2
  164. package/src/hooks/codex-hook.ts +6 -2
  165. package/src/hooks/hook.ts +7 -0
  166. package/src/hooks/pr-body-guard.ts +38 -11
  167. package/src/hooks/pr-room-guard.ts +88 -0
  168. package/src/http/active-sessions.ts +13 -2
  169. package/src/http/agents.ts +11 -3
  170. package/src/http/all-routes.ts +1 -0
  171. package/src/http/api-keys.ts +3 -1
  172. package/src/http/approval-requests.ts +2 -1
  173. package/src/http/apps.ts +118 -190
  174. package/src/http/config.ts +3 -0
  175. package/src/http/context.ts +2 -0
  176. package/src/http/core.ts +39 -2
  177. package/src/http/events.ts +6 -2
  178. package/src/http/favorite-owner.ts +1 -1
  179. package/src/http/fleet-benchmark.ts +79 -30
  180. package/src/http/fs.ts +38 -3
  181. package/src/http/global-config.ts +7 -0
  182. package/src/http/index.ts +3 -1
  183. package/src/http/memory.ts +3 -1
  184. package/src/http/ranking.ts +351 -0
  185. package/src/http/realtime.ts +26 -21
  186. package/src/http/route-def.ts +77 -11
  187. package/src/http/script-runs.ts +2 -1
  188. package/src/http/scripts.ts +8 -0
  189. package/src/http/session-access.ts +179 -0
  190. package/src/http/session-data.ts +10 -2
  191. package/src/http/sessions.ts +212 -12
  192. package/src/http/stats.ts +7 -3
  193. package/src/http/tasks.ts +85 -8
  194. package/src/http/telemetry-ui.ts +1 -1
  195. package/src/http/used-by.ts +64 -20
  196. package/src/http/users.ts +2 -2
  197. package/src/prompts/session-templates.ts +3 -1
  198. package/src/providers/amp-adapter.ts +1 -1
  199. package/src/providers/pi-mono-adapter.ts +15 -0
  200. package/src/providers/reasoning-effort.ts +2 -1
  201. package/src/providers/types.ts +2 -0
  202. package/src/ranking/telemetry-ranking.ts +119 -0
  203. package/src/ranking/usage.ts +57 -0
  204. package/src/rbac/admission.ts +22 -7
  205. package/src/rbac/legacy-policy.ts +2 -0
  206. package/src/rbac/permissions.ts +9 -0
  207. package/src/realtime/auth.ts +69 -0
  208. package/src/realtime/tickets.ts +4 -1
  209. package/src/realtime/transport.ts +77 -9
  210. package/src/scripts-runtime/sdk-allowlist.ts +7 -0
  211. package/src/scripts-runtime/types/stdlib.d.ts +31 -0
  212. package/src/scripts-runtime/types/swarm-sdk.d.ts +31 -0
  213. package/src/server.ts +4 -0
  214. package/src/slack/blocks.ts +18 -0
  215. package/src/slack/dm.ts +29 -0
  216. package/src/telemetry-context.ts +19 -1
  217. package/src/telemetry-contract/EVENTS.md +45 -8
  218. package/src/telemetry-contract/SOURCE.json +38 -4
  219. package/src/telemetry-contract/catalog.json +294 -5
  220. package/src/telemetry-contract/ranking/fixtures/expected.json +30 -0
  221. package/src/telemetry-contract/ranking/fixtures/invalid/bad-category.json +11 -0
  222. package/src/telemetry-contract/ranking/fixtures/invalid/bad-claim.json +11 -0
  223. package/src/telemetry-contract/ranking/fixtures/invalid/blank-description.json +11 -0
  224. package/src/telemetry-contract/ranking/fixtures/invalid/blank-name.json +11 -0
  225. package/src/telemetry-contract/ranking/fixtures/invalid/description-too-long.json +11 -0
  226. package/src/telemetry-contract/ranking/fixtures/invalid/domain-uppercase.json +11 -0
  227. package/src/telemetry-contract/ranking/fixtures/invalid/domain-with-scheme.json +11 -0
  228. package/src/telemetry-contract/ranking/fixtures/invalid/domain-with-www.json +11 -0
  229. package/src/telemetry-contract/ranking/fixtures/invalid/http-source-url.json +11 -0
  230. package/src/telemetry-contract/ranking/fixtures/invalid/missing-description.json +10 -0
  231. package/src/telemetry-contract/ranking/fixtures/invalid/missing-version.json +10 -0
  232. package/src/telemetry-contract/ranking/fixtures/invalid/name-not-string.json +11 -0
  233. package/src/telemetry-contract/ranking/fixtures/invalid/name-too-long.json +11 -0
  234. package/src/telemetry-contract/ranking/fixtures/invalid/not-object.json +1 -0
  235. package/src/telemetry-contract/ranking/fixtures/invalid/null.json +1 -0
  236. package/src/telemetry-contract/ranking/fixtures/invalid/other-with-subcategory.json +11 -0
  237. package/src/telemetry-contract/ranking/fixtures/invalid/oversize.json +1 -0
  238. package/src/telemetry-contract/ranking/fixtures/invalid/short-claim.json +11 -0
  239. package/src/telemetry-contract/ranking/fixtures/invalid/subcategory-other-category.json +11 -0
  240. package/src/telemetry-contract/ranking/fixtures/invalid/trailing-data.json +1 -0
  241. package/src/telemetry-contract/ranking/fixtures/invalid/unknown-field.json +12 -0
  242. package/src/telemetry-contract/ranking/fixtures/invalid/unsupported-version.json +11 -0
  243. package/src/telemetry-contract/ranking/fixtures/invalid/updated-at-not-date.json +11 -0
  244. package/src/telemetry-contract/ranking/fixtures/invalid/updated-at-offset.json +11 -0
  245. package/src/telemetry-contract/ranking/fixtures/invalid/wrong-case-field.json +11 -0
  246. package/src/telemetry-contract/ranking/fixtures/valid/category-without-subcategory.json +11 -0
  247. package/src/telemetry-contract/ranking/fixtures/valid/full.json +11 -0
  248. package/src/telemetry-contract/ranking/fixtures/valid/minimal.json +11 -0
  249. package/src/telemetry-contract/ranking/fixtures/valid/no-claim.json +10 -0
  250. package/src/telemetry-contract/ranking/fixtures/valid/padded-text.json +11 -0
  251. package/src/telemetry-contract/ranking/fixtures/valid/unicode-name.json +11 -0
  252. package/src/telemetry-contract/ranking/listing.v1.schema.json +61 -0
  253. package/src/telemetry-contract/ranking/taxonomy.json +8 -0
  254. package/src/telemetry-contract/ranking-taxonomy.gen.ts +11 -0
  255. package/src/telemetry-contract/types.gen.ts +963 -58
  256. package/src/telemetry-identity.ts +47 -9
  257. package/src/telemetry-snapshot.ts +9 -1
  258. package/src/telemetry-ui-events.ts +9 -2
  259. package/src/telemetry.ts +40 -5
  260. package/src/tests/app-action-run-tool.test.ts +178 -0
  261. package/src/tests/app-row-tools.test.ts +360 -0
  262. package/src/tests/apps-rbac.test.ts +189 -2
  263. package/src/tests/apps-script-types.test.ts +16 -3
  264. package/src/tests/credential-check.test.ts +38 -0
  265. package/src/tests/db-extraction-contract.test.ts +1 -0
  266. package/src/tests/db-task-read-contract.test.ts +1 -0
  267. package/src/tests/docs-index-footprint.test.js +2 -2
  268. package/src/tests/fleet-benchmark.test.ts +122 -2
  269. package/src/tests/http-users.test.ts +62 -1
  270. package/src/tests/model-catalog-table.test.ts +63 -0
  271. package/src/tests/model-profiles-api.test.ts +19 -7
  272. package/src/tests/models-catalog.test.ts +50 -0
  273. package/src/tests/onboarding.test.ts +21 -0
  274. package/src/tests/org-identity.test.ts +44 -0
  275. package/src/tests/org-website.test.ts +62 -0
  276. package/src/tests/pi-mono-adapter.test.ts +23 -0
  277. package/src/tests/pr-body-leaks.test.ts +4 -0
  278. package/src/tests/pr-room-guard.test.ts +242 -0
  279. package/src/tests/ranking-listing.test.ts +97 -0
  280. package/src/tests/ranking-route.test.ts +321 -0
  281. package/src/tests/ranking-usage.test.ts +50 -0
  282. package/src/tests/rbac-admission-e2e.test.ts +8 -0
  283. package/src/tests/rbac-admission.test.ts +38 -0
  284. package/src/tests/rbac-charact-http.test.ts +4 -3
  285. package/src/tests/rbac-engine.test.ts +2 -0
  286. package/src/tests/rbac-roles.test.ts +2 -0
  287. package/src/tests/realtime-room-surfaces.test.ts +3 -1
  288. package/src/tests/realtime-session-join-race.test.ts +142 -0
  289. package/src/tests/realtime-tickets.test.ts +24 -17
  290. package/src/tests/realtime-transport.test.ts +91 -0
  291. package/src/tests/reasoning-effort.test.ts +39 -3
  292. package/src/tests/runner-harness-telemetry-env.test.ts +56 -1
  293. package/src/tests/session-route-posture.test.ts +639 -0
  294. package/src/tests/session-sharing-routes.test.ts +282 -0
  295. package/src/tests/session-sharing.test.ts +526 -0
  296. package/src/tests/sessions-detail-batch.test.ts +7 -1
  297. package/src/tests/slack-tool-blocks.test.ts +101 -0
  298. package/src/tests/slack-update.test.ts +55 -0
  299. package/src/tests/slack-user-dm.test.ts +177 -0
  300. package/src/tests/swarm-tool-result-gate.test.ts +2 -4
  301. package/src/tests/telemetry-context.test.ts +128 -2
  302. package/src/tests/telemetry-ui-route.test.ts +123 -0
  303. package/src/tests/tool-annotations.test.ts +3 -2
  304. package/src/tests/used-by-route.test.ts +153 -9
  305. package/src/tests/workflow-agent-task-retry.test.ts +130 -4
  306. package/src/tests/workflow-wait-recovery.test.ts +116 -4
  307. package/src/tools/app-action-run.ts +63 -0
  308. package/src/tools/app-rows.ts +234 -0
  309. package/src/tools/model-catalog/index.ts +1 -1
  310. package/src/tools/slack-post.ts +18 -12
  311. package/src/tools/slack-read.ts +13 -1
  312. package/src/tools/slack-reply.ts +7 -10
  313. package/src/tools/slack-start-thread.ts +18 -11
  314. package/src/tools/slack-update.ts +2 -9
  315. package/src/tools/tool-config.ts +8 -0
  316. package/src/tools/utils.ts +1 -1
  317. package/src/tools/workflows/retry-workflow-run.ts +1 -1
  318. package/src/types.ts +52 -0
  319. package/src/utils/company-profile.ts +24 -0
  320. package/src/utils/org-identity.ts +33 -0
  321. package/src/utils/org-website.ts +58 -21
  322. package/src/workflows/recovery.ts +10 -22
  323. package/src/workflows/resume.ts +16 -0
  324. package/src/workflows/task-step-routing.ts +47 -7
  325. package/templates/skills/apps/SKILL.md +58 -2
  326. package/templates/skills/apps/content.md +58 -2
  327. package/dist/handlers-tb3xgjnm.js +0 -37
  328. package/dist/index-nyfcdpky.js +0 -39
  329. package/dist/index-vjn3wbzf.js +0 -38
  330. package/dist/lead-61kqp604.js +0 -76
  331. package/dist/worker-4ptnn1ge.js +0 -76
  332. package/dist/{cli-n5mrsg0f.js → cli-60cgh1rv.js} +3 -3
@@ -17,6 +17,7 @@ import {
17
17
  checkPiMonoCredentials,
18
18
  createPiRuntimeAuth,
19
19
  extractPiAssistantText,
20
+ listPiOpencodeGoModelIds,
20
21
  PiMonoAdapter,
21
22
  resolveModel,
22
23
  type SessionModelsJson,
@@ -457,6 +458,18 @@ describe("Model name mapping", () => {
457
458
  });
458
459
  });
459
460
 
461
+ describe("listPiOpencodeGoModelIds", () => {
462
+ test("every reported opencode-go id resolves, so a picked id never falls back", () => {
463
+ const ids = listPiOpencodeGoModelIds();
464
+ expect(ids).toContain("deepseek-v4.1-flash");
465
+ for (const id of ids) {
466
+ expect(resolveModel(`opencode-go/${id}`, {})?.id).toBe(id);
467
+ }
468
+ expect(ids).not.toContain("deepseek-v4-flash");
469
+ expect(resolveModel("opencode-go/deepseek-v4-flash", {})).toBeUndefined();
470
+ });
471
+ });
472
+
460
473
  describe("resolveModel — OpenRouter reroute for anthropic shortnames", () => {
461
474
  // Regression coverage for task 37a4a87a: workers spawned with
462
475
  // `provider: pi` + `OPENROUTER_API_KEY` (no ANTHROPIC_API_KEY) and a task
@@ -546,6 +559,16 @@ describe("createPiRuntimeAuth", () => {
546
559
  });
547
560
  });
548
561
 
562
+ test("passes OPENCODE_API_KEY to pi opencode-go runtime auth", async () => {
563
+ const modelRuntime = await createPiRuntimeAuth({
564
+ OPENCODE_API_KEY: "example-opencode-runtime",
565
+ });
566
+
567
+ await expect(modelRuntime.getAuth("opencode-go")).resolves.toMatchObject({
568
+ auth: { apiKey: "example-opencode-runtime" },
569
+ });
570
+ });
571
+
549
572
  test("passes GEMINI_API_KEY to pi google runtime auth", async () => {
550
573
  const modelRuntime = await createPiRuntimeAuth({
551
574
  GEMINI_API_KEY: "example-gemini-runtime",
@@ -339,14 +339,18 @@ describe("parseGhPrCommands", () => {
339
339
  );
340
340
  expect(calls).toEqual([
341
341
  {
342
+ action: "create",
342
343
  cwd: "/tmp/wt",
343
344
  repos: ["o/r"],
345
+ resolvedRepos: ["o/r"],
344
346
  alsoCheckout: false,
345
347
  unknownTarget: false,
346
348
  texts: ["t"],
349
+ bodyTexts: [],
347
350
  bodyFiles: ["body.md"],
348
351
  unresolvedBodyFiles: [],
349
352
  opaqueBody: false,
353
+ externalBody: false,
350
354
  },
351
355
  ]);
352
356
  });
@@ -0,0 +1,242 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { mkdtemp, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { codexPreToolUseBlock } from "../hooks/codex-hook";
6
+ import { gitRemoteOrigin, guardGhPrRoom, type PrRoomGuardDeps } from "../hooks/pr-room-guard";
7
+ import { expectChildOk, runChild } from "./test-proc";
8
+
9
+ const ROOM_LINE = "PR room: prr-abcde23457";
10
+ const BLOCK_REASON =
11
+ 'This repo uses PR rooms. Create the room first with the pr-room skill (app action createRoom). Then pass the returned prBody with --body-file. The body must contain the line "PR room: prr-...".';
12
+
13
+ function fakeDeps(overrides: Partial<PrRoomGuardDeps> = {}): PrRoomGuardDeps {
14
+ return {
15
+ env: { PR_ROOM_REPOS: "owner/repo" },
16
+ readFile: async () => "No room marker",
17
+ remoteOrigin: async () => "https://github.com/owner/repo.git",
18
+ ...overrides,
19
+ };
20
+ }
21
+
22
+ const check = (command: string, deps = fakeDeps()) => guardGhPrRoom({ command }, "/w", deps);
23
+
24
+ describe("guardGhPrRoom", () => {
25
+ test.each([undefined, "", " , , "])("allows disabled configuration %p", async (value) => {
26
+ expect(
27
+ await check(
28
+ "gh pr create -R owner/repo -b plain",
29
+ fakeDeps({ env: { PR_ROOM_REPOS: value } }),
30
+ ),
31
+ ).toBeNull();
32
+ });
33
+
34
+ test("blocks a configured repo without a room marker", async () => {
35
+ expect(await check("gh pr create --repo owner/repo --body plain")).toBe(BLOCK_REASON);
36
+ expect(await check("gh pr create -Rowner/repo")).toBe(BLOCK_REASON);
37
+ });
38
+
39
+ test("allows a marker in the inline body", async () => {
40
+ expect(await check(`gh pr create -R owner/repo --body 'Summary\n${ROOM_LINE}'`)).toBeNull();
41
+ });
42
+
43
+ test("resolves body files relative to cd", async () => {
44
+ const paths: string[] = [];
45
+ const deps = fakeDeps({
46
+ readFile: async (path) => {
47
+ paths.push(path);
48
+ return ROOM_LINE;
49
+ },
50
+ });
51
+ expect(
52
+ await check("cd /checkout && gh pr create -R owner/repo --body-file body.md", deps),
53
+ ).toBeNull();
54
+ expect(paths).toEqual(["/checkout/body.md"]);
55
+ });
56
+
57
+ test("allows a heredoc body with a marker", async () => {
58
+ expect(
59
+ await check(`gh pr create -R owner/repo --body-file - <<'EOF'\n${ROOM_LINE}\nEOF`),
60
+ ).toBeNull();
61
+ });
62
+
63
+ test("blocks resolved files and heredocs without a marker", async () => {
64
+ expect(await check("gh pr create -R owner/repo -F body.md")).toBe(BLOCK_REASON);
65
+ expect(await check("gh pr create -R owner/repo -F - <<'EOF'\nplain\nEOF")).toBe(BLOCK_REASON);
66
+ });
67
+
68
+ test("allows another repo without reading its body", async () => {
69
+ expect(await check("gh pr create -R other/repo -b plain")).toBeNull();
70
+ });
71
+
72
+ test.each([
73
+ "GH_REPO=owner/repo gh pr create -b plain",
74
+ "export GH_REPO=owner/repo && gh pr create -b plain",
75
+ ])("checks command targeting: %s", async (command) => {
76
+ expect(await check(command)).toBe(BLOCK_REASON);
77
+ });
78
+
79
+ test("allows an ambiguous target unless every candidate is configured", async () => {
80
+ const otherCheckout = fakeDeps({ remoteOrigin: async () => "https://github.com/other/repo" });
81
+ expect(await check("GH_REPO=owner/repo && gh pr create -b plain", otherCheckout)).toBeNull();
82
+ expect(await check("GH_REPO=owner/repo && gh pr create -b plain")).toBe(BLOCK_REASON);
83
+ expect(await check("gh pr create -R owner/repo -R other/repo -b plain")).toBeNull();
84
+ });
85
+
86
+ test("checks inherited GH_REPO and honors an explicit override", async () => {
87
+ const deps = fakeDeps({ env: { PR_ROOM_REPOS: "owner/repo", GH_REPO: "owner/repo" } });
88
+ expect(await check("gh pr create -b plain", deps)).toBe(BLOCK_REASON);
89
+ expect(await check("gh pr create -R other/repo -b plain", deps)).toBeNull();
90
+ });
91
+
92
+ test("trims configured repos and matches case insensitively", async () => {
93
+ const deps = fakeDeps({ env: { PR_ROOM_REPOS: " other/repo, OWNER/REPO , " } });
94
+ expect(await check("gh -R Owner/Repo pr create -b plain", deps)).toBe(BLOCK_REASON);
95
+ });
96
+
97
+ test("allows edits and unrelated commands", async () => {
98
+ expect(await check("gh pr edit 123 -R owner/repo -b plain")).toBeNull();
99
+ expect(await check("gh pr view 123 -R owner/repo")).toBeNull();
100
+ expect(await guardGhPrRoom(undefined, "/w", fakeDeps())).toBeNull();
101
+ });
102
+
103
+ test.each([
104
+ "https://github.com/Owner/Repo.git",
105
+ "https://github.com/Owner/Repo",
106
+ "git@github.com:Owner/Repo.git",
107
+ "ssh://git@github.com/Owner/Repo.git",
108
+ ])("resolves checkout remote %s", async (remote) => {
109
+ const lookups: string[] = [];
110
+ const deps = fakeDeps({
111
+ remoteOrigin: async (cwd) => {
112
+ lookups.push(cwd);
113
+ return remote;
114
+ },
115
+ });
116
+ expect(await check("cd /checkout && gh pr create -b plain", deps)).toBe(BLOCK_REASON);
117
+ expect(lookups).toEqual(["/checkout"]);
118
+ });
119
+
120
+ test("allows failed remote lookup and unsupported remote forms", async () => {
121
+ expect(
122
+ await check("gh pr create -b plain", fakeDeps({ remoteOrigin: async () => "local/path" })),
123
+ ).toBeNull();
124
+ expect(
125
+ await check(
126
+ "gh pr create -b plain",
127
+ fakeDeps({
128
+ remoteOrigin: async () => {
129
+ throw new Error("no checkout");
130
+ },
131
+ }),
132
+ ),
133
+ ).toBeNull();
134
+ });
135
+
136
+ // git exports GIT_DIR to a pre-push hook in a linked worktree. The lookup then reads that repo.
137
+ test.skipIf(process.env.GIT_DIR !== undefined)(
138
+ "allows a checkout remote lookup that does not finish",
139
+ async () => {
140
+ const dir = await mkdtemp(join(tmpdir(), "pr-room-fifo-"));
141
+ try {
142
+ expectChildOk(await runChild(["git", "init", "-q", dir]), "git init");
143
+ await rm(join(dir, ".git", "config"));
144
+ expectChildOk(await runChild(["mkfifo", join(dir, ".git", "config")]), "mkfifo");
145
+ await expect(gitRemoteOrigin(dir, 200)).rejects.toThrow();
146
+ const deps = fakeDeps({ remoteOrigin: (cwd) => gitRemoteOrigin(cwd, 200) });
147
+ expect(await guardGhPrRoom({ command: "gh pr create -b plain" }, dir, deps)).toBeNull();
148
+ } finally {
149
+ await rm(dir, { recursive: true, force: true });
150
+ }
151
+ },
152
+ );
153
+
154
+ test.each([
155
+ 'gh pr create -R "$UNKNOWN" -b plain',
156
+ 'gh pr create -R owner/repo -b "$UNKNOWN"',
157
+ 'gh pr create -R owner/repo -F "$UNKNOWN"',
158
+ "cd - && gh pr create -R owner/repo -b plain",
159
+ 'cd "$UNKNOWN" && gh pr create -b plain',
160
+ "read GH_REPO && gh pr create -b plain",
161
+ ])("allows unresolved inputs: %s", async (command) => {
162
+ expect(await check(command)).toBeNull();
163
+ });
164
+
165
+ test("allows unreadable body files", async () => {
166
+ const deps = fakeDeps({
167
+ readFile: async () => {
168
+ throw new Error("unreadable");
169
+ },
170
+ });
171
+ expect(await check("gh pr create -R owner/repo -F missing.md", deps)).toBeNull();
172
+ });
173
+
174
+ test("resolves known variables without changing leak guard texts", async () => {
175
+ expect(await check('REPO=owner/repo && gh pr create -R "$REPO" -b plain')).toBe(BLOCK_REASON);
176
+ expect(await check(`BODY='${ROOM_LINE}' && gh pr create -R owner/repo -b "$BODY"`)).toBeNull();
177
+ });
178
+
179
+ test.each([
180
+ "cat room.md | gh pr create -R owner/repo -F -",
181
+ "printf plain | gh pr create -R owner/repo -F -",
182
+ "gh pr create -R owner/repo -b $(cat room.md)",
183
+ "gh pr create -R owner/repo --fill",
184
+ "gh pr create -R owner/repo -f",
185
+ "gh pr create -R owner/repo --fill-first",
186
+ "gh pr create -R owner/repo --fill-verbose",
187
+ "gh pr create -R owner/repo -T template.md -b plain",
188
+ "gh pr create -R owner/repo --template=template.md",
189
+ "gh pr create -R owner/repo -dw -b plain",
190
+ "gh pr create -R owner/repo --web",
191
+ "gh pr create -R owner/repo -e",
192
+ "gh pr create -R owner/repo --editor",
193
+ "gh pr create -R owner/repo --recover input.json",
194
+ ])("allows a body the guard cannot read: %s", async (command) => {
195
+ expect(await check(command)).toBeNull();
196
+ });
197
+
198
+ test.each([
199
+ "PR room: prr-abcde2345",
200
+ "PR room: prr-abcde234578",
201
+ "PR room: prr-ABCDE23457",
202
+ "prefix PR room: prr-abcde23457",
203
+ ])("rejects an invalid marker: %s", async (line) => {
204
+ expect(await check(`gh pr create -R owner/repo -b '${line}'`)).toBe(BLOCK_REASON);
205
+ });
206
+
207
+ test("does not accept a marker only in the title", async () => {
208
+ expect(await check(`gh pr create -R owner/repo -t '${ROOM_LINE}' -b plain`)).toBe(BLOCK_REASON);
209
+ });
210
+
211
+ test("checks every create invocation", async () => {
212
+ expect(await check(`gh pr edit 1 -b plain && gh pr create -R owner/repo -b plain`)).toBe(
213
+ BLOCK_REASON,
214
+ );
215
+ });
216
+
217
+ test("Codex runs the room guard after the leak guard, including app-server sessions", async () => {
218
+ const roomDeps = fakeDeps();
219
+ const leakDeps = {
220
+ env: { SWARM_CODEX_APP_SERVER: "1" },
221
+ readFile: roomDeps.readFile,
222
+ repoVisibility: async () => "PUBLIC",
223
+ };
224
+ const msg = {
225
+ hook_event_name: "PreToolUse",
226
+ cwd: "/w",
227
+ tool_input: { command: "gh pr create -R owner/repo -b plain" },
228
+ };
229
+ expect(await codexPreToolUseBlock(msg, leakDeps, roomDeps)).toBe(BLOCK_REASON);
230
+ const leaky = {
231
+ ...msg,
232
+ tool_input: {
233
+ command:
234
+ "gh pr create -R owner/repo -b 'https://acme.slack.com/archives/C01234567/p1700000000000000'",
235
+ },
236
+ };
237
+ expect(await codexPreToolUseBlock(leaky, leakDeps, roomDeps)).toContain("PR body leak check:");
238
+ expect(
239
+ await codexPreToolUseBlock({ ...msg, hook_event_name: "PostToolUse" }, leakDeps, roomDeps),
240
+ ).toBeNull();
241
+ });
242
+ });
@@ -0,0 +1,97 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { readdirSync, readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { isInternalConfigKey, validateConfigValue } from "../be/swarm-config-guard";
5
+ import { buildListing, parseTelemetryRanking } from "../ranking/telemetry-ranking";
6
+ import { RANKING_TAXONOMY } from "../telemetry-contract/ranking-taxonomy.gen";
7
+ import { orgIdentityStatus } from "../utils/org-identity";
8
+
9
+ const FIXTURES = join(import.meta.dir, "..", "telemetry-contract", "ranking", "fixtures");
10
+ const read = (kind: string, file: string) => readFileSync(join(FIXTURES, kind, file), "utf8");
11
+
12
+ describe("telemetry_ranking contract fixtures", () => {
13
+ const expected = JSON.parse(readFileSync(join(FIXTURES, "expected.json"), "utf8")) as {
14
+ invalid: Record<string, string>;
15
+ };
16
+
17
+ test("the fixture set is complete", () => {
18
+ expect(readdirSync(join(FIXTURES, "valid")).length).toBeGreaterThan(0);
19
+ expect(readdirSync(join(FIXTURES, "invalid")).sort()).toEqual(
20
+ Object.keys(expected.invalid).sort(),
21
+ );
22
+ });
23
+
24
+ for (const file of readdirSync(join(FIXTURES, "valid"))) {
25
+ test(`valid/${file} parses`, () => {
26
+ expect(() => parseTelemetryRanking(read("valid", file))).not.toThrow();
27
+ });
28
+ }
29
+
30
+ for (const file of readdirSync(join(FIXTURES, "invalid"))) {
31
+ test(`invalid/${file} is rejected (${expected.invalid[file]})`, () => {
32
+ expect(() => parseTelemetryRanking(read("invalid", file))).toThrow();
33
+ });
34
+ }
35
+ });
36
+
37
+ describe("buildListing", () => {
38
+ const identity = orgIdentityStatus({ SWARM_ORG_NAME: "Acme", SWARM_ORG_WEBSITE: "acme.dev" });
39
+
40
+ test("copies the name and domain from the org identity and blanks to null", () => {
41
+ const listing = buildListing(
42
+ identity,
43
+ {
44
+ category: "engineering",
45
+ subcategory: "qa-testing",
46
+ description: " ",
47
+ sourceCodeUrl: null,
48
+ },
49
+ new Date("2026-10-18T10:00:00Z"),
50
+ );
51
+ expect(listing).toEqual({
52
+ v: 1,
53
+ name: "Acme",
54
+ domain: "acme.dev",
55
+ category: "engineering",
56
+ subcategory: "qa-testing",
57
+ description: null,
58
+ sourceCodeUrl: null,
59
+ updatedAt: "2026-10-18T10:00:00.000Z",
60
+ });
61
+ });
62
+
63
+ test("refuses a missing identity and an http source URL", () => {
64
+ expect(() =>
65
+ buildListing(orgIdentityStatus({ SWARM_ORG_NAME: "Swarm", SWARM_ORG_WEBSITE: "acme.dev" }), {
66
+ category: "other",
67
+ }),
68
+ ).toThrow("SWARM_ORG_NAME");
69
+ expect(() =>
70
+ buildListing(identity, { category: "other", sourceCodeUrl: "http://github.com/acme" }),
71
+ ).toThrow();
72
+ });
73
+
74
+ test("a v2.4.0 listing with a claim still parses", () => {
75
+ const legacy = { ...JSON.parse(read("valid", "full.json")), claim: `rk_${"0".repeat(32)}` };
76
+ expect(parseTelemetryRanking(JSON.stringify(legacy)).claim).toBe(legacy.claim);
77
+ });
78
+
79
+ test("the taxonomy comes from the vendored contract", () => {
80
+ expect(RANKING_TAXONOMY).toEqual(
81
+ JSON.parse(readFileSync(join(FIXTURES, "..", "taxonomy.json"), "utf8")),
82
+ );
83
+ });
84
+ });
85
+
86
+ describe("config guard", () => {
87
+ test("telemetry_ranking is internal and validated", () => {
88
+ expect(isInternalConfigKey("telemetry_ranking")).toBe(true);
89
+ expect(validateConfigValue("telemetry_ranking", "{}")).toContain("telemetry_ranking");
90
+ expect(validateConfigValue("telemetry_ranking", read("valid", "full.json"))).toBeNull();
91
+ });
92
+
93
+ test("PUBLIC_RANKING_ENABLED is a boolean", () => {
94
+ expect(validateConfigValue("PUBLIC_RANKING_ENABLED", "true")).toBeNull();
95
+ expect(validateConfigValue("PUBLIC_RANKING_ENABLED", "yes please")).not.toBeNull();
96
+ });
97
+ });