@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
@@ -8,6 +8,7 @@ import {
8
8
  redeemRealtimeTicket,
9
9
  sweepRealtimeTickets,
10
10
  } from "../realtime/tickets";
11
+ import { type HttpRequestAuth, setRequestAuth } from "../utils/request-auth-context";
11
12
 
12
13
  const auth = { kind: "operator", fingerprint: "test-operator" } as const;
13
14
 
@@ -46,26 +47,32 @@ describe("realtime tickets", () => {
46
47
  expect(redeemRealtimeTicket(newest.ticket, 4_001)).toEqual(auth);
47
48
  });
48
49
 
49
- test("the ticket route answers 404 while Comb is off", async () => {
50
+ test("the ticket route refuses agents and serves the dashboard with Comb off", async () => {
50
51
  const previous = process.env.COMB_ENABLED;
51
52
  process.env.COMB_ENABLED = "false";
52
53
  try {
53
- let status = 0;
54
- const res = {
55
- writeHead: (code: number) => {
56
- status = code;
57
- },
58
- end: () => {},
59
- } as unknown as ServerResponse;
60
- const req = { method: "POST", headers: {} } as IncomingMessage;
61
- const handled = await handleRealtimeTicket(
62
- req,
63
- res,
64
- ["api", "realtime", "ticket"],
65
- new URLSearchParams(),
66
- );
67
- expect(handled).toBe(true);
68
- expect(status).toBe(404);
54
+ const ticketStatus = async (requestAuth: HttpRequestAuth | null) => {
55
+ let status = 0;
56
+ const res = {
57
+ writeHead: (code: number) => {
58
+ status = code;
59
+ },
60
+ end: () => {},
61
+ } as unknown as ServerResponse;
62
+ const req = { method: "POST", headers: {} } as IncomingMessage;
63
+ if (requestAuth) setRequestAuth(req, requestAuth);
64
+ const handled = await handleRealtimeTicket(
65
+ req,
66
+ res,
67
+ ["api", "realtime", "ticket"],
68
+ new URLSearchParams(),
69
+ );
70
+ expect(handled).toBe(true);
71
+ return status;
72
+ };
73
+ // Session presence uses the ticket too, so Comb being off no longer hides the route.
74
+ expect(await ticketStatus(auth)).toBe(200);
75
+ expect(await ticketStatus(null)).toBe(403);
69
76
  } finally {
70
77
  if (previous === undefined) delete process.env.COMB_ENABLED;
71
78
  else process.env.COMB_ENABLED = previous;
@@ -655,6 +655,97 @@ describe("realtime transport", () => {
655
655
  }
656
656
  });
657
657
 
658
+ test("session presence: the first joiner creates the room, and a viewer needs read access", async () => {
659
+ const owner = await createUserToken("Session Owner");
660
+ const viewer = await createUserToken("Session Viewer");
661
+ const created = await api("POST", "/api/tasks", {
662
+ body: { task: "Fix flaky deploy", requestedByUserId: owner.id, source: "ui" },
663
+ });
664
+ expect(created.status).toBe(201);
665
+ const rootId = ((await created.json()) as { id: string }).id;
666
+ const namespace = `presence:session:${rootId}`;
667
+ const ownerSocket = await openSocket(
668
+ {},
669
+ `${socketUrl}?ticket=${(await issueTicket(owner.token)).ticket}`,
670
+ );
671
+ const viewerSocket = await openSocket(
672
+ {},
673
+ `${socketUrl}?ticket=${(await issueTicket(viewer.token)).ticket}`,
674
+ );
675
+ try {
676
+ await ownerSocket.next((frame) => frame.type === "hello");
677
+ await viewerSocket.next((frame) => frame.type === "hello");
678
+ // Nobody is in the room yet: this join creates it.
679
+ const ownerJoined = await join(ownerSocket, 1, "default", namespace);
680
+ expect(ownerJoined.type).toBe("result");
681
+
682
+ viewerSocket.send({ id: 2, op: "join", name: "default", namespace, schemaVersion: 1 });
683
+ const denied = await viewerSocket.next((frame) => frame.type === "error" && frame.id === 2);
684
+ expect(denied.error).toContain("access");
685
+
686
+ const shared = await api("PUT", `/api/sessions/${rootId}/shares`, {
687
+ headers: { Authorization: `Bearer ${owner.token}` },
688
+ body: { everyone: "read", users: [] },
689
+ });
690
+ expect(shared.status).toBe(200);
691
+ expect((await join(viewerSocket, 3, "default", namespace)).type).toBe("result");
692
+ } finally {
693
+ await closeSocket(ownerSocket);
694
+ await closeSocket(viewerSocket);
695
+ }
696
+ });
697
+
698
+ test("session presence: revoking read access evicts the viewer from the room", async () => {
699
+ const owner = await createUserToken("Revoking Owner");
700
+ const viewer = await createUserToken("Revoked Viewer");
701
+ const created = await api("POST", "/api/tasks", {
702
+ body: { task: "Private incident", requestedByUserId: owner.id, source: "ui" },
703
+ });
704
+ expect(created.status).toBe(201);
705
+ const rootId = ((await created.json()) as { id: string }).id;
706
+ const namespace = `presence:session:${rootId}`;
707
+ const share = async (everyone: "read" | "none") => {
708
+ const response = await api("PUT", `/api/sessions/${rootId}/shares`, {
709
+ headers: { Authorization: `Bearer ${owner.token}` },
710
+ body: { everyone, users: [] },
711
+ });
712
+ expect(response.status).toBe(200);
713
+ };
714
+ const ownerSocket = await openSocket(
715
+ {},
716
+ `${socketUrl}?ticket=${(await issueTicket(owner.token)).ticket}`,
717
+ );
718
+ const viewerSocket = await openSocket(
719
+ {},
720
+ `${socketUrl}?ticket=${(await issueTicket(viewer.token)).ticket}`,
721
+ );
722
+ try {
723
+ await ownerSocket.next((frame) => frame.type === "hello");
724
+ await viewerSocket.next((frame) => frame.type === "hello");
725
+ await share("read");
726
+ expect((await join(ownerSocket, 1, "default", namespace)).type).toBe("result");
727
+ expect((await join(viewerSocket, 2, "default", namespace)).type).toBe("result");
728
+ viewerSocket.frames.splice(0);
729
+
730
+ await share("none");
731
+ const evicted = await viewerSocket.next(
732
+ (frame) => frame.type === "error" && frame.namespace === namespace,
733
+ );
734
+ expect(evicted.error).toContain("access");
735
+
736
+ ownerSocket.send({ id: 3, op: "presence", namespace, data: { typing: true } });
737
+ await ownerSocket.next((frame) => frame.type === "result" && frame.id === 3);
738
+ await Bun.sleep(100);
739
+ const leaked = viewerSocket.frames.filter(
740
+ (frame) => frame.type === "presence" && JSON.stringify(frame.peers).includes("typing"),
741
+ );
742
+ expect(leaked).toEqual([]);
743
+ } finally {
744
+ await closeSocket(ownerSocket);
745
+ await closeSocket(viewerSocket);
746
+ }
747
+ });
748
+
658
749
  test("refuses agent access to Comb presence namespaces", async () => {
659
750
  const agentId = await registerAgent();
660
751
  const client = await openSocket({
@@ -212,6 +212,13 @@ describe("applyReasoningEffort — pi-session shape", () => {
212
212
  sessionOptions: { thinkingLevel: "medium" },
213
213
  });
214
214
  });
215
+
216
+ test("max passes through for an opencode-go model that declares it", () => {
217
+ expect(applyReasoningEffort("pi", "opencode-go/deepseek-v4-flash", "max")).toEqual({
218
+ kind: "pi-session",
219
+ sessionOptions: { thinkingLevel: "max" },
220
+ });
221
+ });
215
222
  });
216
223
 
217
224
  describe("applyReasoningEffort — opencode-options shape", () => {
@@ -245,6 +252,30 @@ describe("applyReasoningEffort — opencode-options shape", () => {
245
252
  kind: "noop",
246
253
  });
247
254
  });
255
+
256
+ test("opencode-go passes max through on its OpenAI-compatible transport", () => {
257
+ // `opencode-go/deepseek-v4-flash` declares low|high|max in the snapshot.
258
+ expect(reasoningCapability("opencode", "opencode-go/deepseek-v4-flash").levels).toEqual([
259
+ "low",
260
+ "high",
261
+ "max",
262
+ ]);
263
+ expect(applyReasoningEffort("opencode", "opencode-go/deepseek-v4-flash", "max")).toEqual({
264
+ kind: "opencode-options",
265
+ providerId: "opencode-go",
266
+ modelId: "deepseek-v4-flash",
267
+ options: { reasoningEffort: "max" },
268
+ });
269
+ });
270
+
271
+ test("anthropic max uses the effort key opencode's Anthropic transport reads", () => {
272
+ expect(applyReasoningEffort("opencode", "anthropic/claude-opus-5-5", "max")).toEqual({
273
+ kind: "opencode-options",
274
+ providerId: "anthropic",
275
+ modelId: "claude-opus-5-5",
276
+ options: { effort: "max" },
277
+ });
278
+ });
248
279
  });
249
280
 
250
281
  // The offered levels, the API's validation and the harness application all read the same
@@ -266,16 +297,21 @@ describe("harness × model → effort matrix", () => {
266
297
  },
267
298
  { harness: "codex", model: "gpt-6-astra", levels: ["low", "medium", "high", "xhigh", "max"] },
268
299
  { harness: "codex", model: "gpt-5.1-codex", levels: ["low", "medium", "high"] },
269
- { harness: "pi", model: "openrouter/deepseek/deepseek-v4.1-flash", levels: ["low", "high"] },
300
+ {
301
+ harness: "pi",
302
+ model: "openrouter/deepseek/deepseek-v4.1-flash",
303
+ levels: ["low", "high", "max"],
304
+ },
270
305
  {
271
306
  harness: "pi",
272
307
  model: "openrouter/anthropic/claude-opus-5.5",
273
- levels: ["low", "medium", "high", "xhigh"],
308
+ levels: ["low", "medium", "high", "xhigh", "max"],
274
309
  },
275
310
  {
276
311
  harness: "opencode",
277
312
  model: "openrouter/deepseek/deepseek-v4.1-flash",
278
- levels: ["low", "high"],
313
+ // The facts declare max, and opencode passes it through.
314
+ levels: ["low", "high", "max"],
279
315
  },
280
316
  { harness: "pi", model: "openrouter/qwen/qwen3-coder-flash", levels: [] },
281
317
  { harness: "claude", model: "totally-custom-model-xyz", levels: [] },
@@ -1,6 +1,7 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
  import { join } from "node:path";
3
- import { withHarnessTelemetryEnv } from "../commands/runner";
3
+ import { applyResolvedEnvToProcessEnv, withHarnessTelemetryEnv } from "../commands/runner";
4
+ import { _resetTelemetryStateForTests, initTelemetry, track } from "../telemetry";
4
5
  import { CHILD_PROCESS_TEST_BUDGET_MS, runChild } from "./test-proc";
5
6
 
6
7
  const TELEMETRY_PATH = join(import.meta.dir, "..", "telemetry.ts");
@@ -86,6 +87,60 @@ describe("withHarnessTelemetryEnv", () => {
86
87
  });
87
88
  });
88
89
 
90
+ test("worker telemetry receives and clears company profile through resolved config", async () => {
91
+ const profile = {
92
+ SWARM_ORG_WEBSITE: "acme.com",
93
+ SWARM_ORG_TEAM_SIZE: "2-10",
94
+ SWARM_ORG_USE_CASE: "ops",
95
+ SWARM_ORG_ACQUISITION_SOURCE: "github",
96
+ };
97
+ const saved = Object.fromEntries(
98
+ [...Object.keys(profile), "ANONYMIZED_TELEMETRY"].map((key) => [key, process.env[key]]),
99
+ );
100
+ const originalFetch = globalThis.fetch;
101
+ const sent: Array<{ context: Record<string, unknown> }> = [];
102
+ try {
103
+ process.env.ANONYMIZED_TELEMETRY = "true";
104
+ _resetTelemetryStateForTests();
105
+ globalThis.fetch = (async (_url: string, init?: { body?: string }) => {
106
+ sent.push(JSON.parse(init?.body ?? "{}"));
107
+ return new Response(null, { status: 204 });
108
+ }) as typeof fetch;
109
+ applyResolvedEnvToProcessEnv(profile);
110
+ const config: Record<string, string> = {
111
+ telemetry_installation_id: "install_worker_profile",
112
+ telemetry_org_id: "org_0123456789abcdef",
113
+ telemetry_org_domain: "acme.com",
114
+ };
115
+ await initTelemetry(
116
+ "worker",
117
+ (key) => config[key],
118
+ () => {},
119
+ );
120
+ track({ event: "session.started", properties: { agentId: crypto.randomUUID() } });
121
+ expect(sent[0]?.context).toMatchObject({
122
+ org_website: "acme.com",
123
+ org_domain: "acme.com",
124
+ team_size: "2-10",
125
+ use_case: "ops",
126
+ acquisition_source: "github",
127
+ });
128
+ applyResolvedEnvToProcessEnv(Object.fromEntries(Object.keys(profile).map((key) => [key, ""])));
129
+ track({ event: "session.started", properties: { agentId: crypto.randomUUID() } });
130
+ expect(sent[1]?.context).not.toHaveProperty("org_website");
131
+ expect(sent[1]?.context).not.toHaveProperty("team_size");
132
+ expect(sent[1]?.context).not.toHaveProperty("use_case");
133
+ expect(sent[1]?.context.acquisition_source).toBeNull();
134
+ } finally {
135
+ for (const [key, value] of Object.entries(saved)) {
136
+ if (value === undefined) delete process.env[key];
137
+ else process.env[key] = value;
138
+ }
139
+ globalThis.fetch = originalFetch;
140
+ _resetTelemetryStateForTests();
141
+ }
142
+ });
143
+
89
144
  describe("API boot telemetry environment", () => {
90
145
  test(
91
146
  "an unprefixed API boot from an agent session emits test",