@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
@@ -0,0 +1,29 @@
1
+ import type { WebClient } from "@slack/web-api";
2
+
3
+ /** Slack user ids start with U (or W on Enterprise Grid); conversation ids start with C, G or D. */
4
+ export function isSlackUserId(id: string): boolean {
5
+ return /^[UW][A-Z0-9]+$/.test(id);
6
+ }
7
+
8
+ /**
9
+ * Resolves a user id to the bot's own DM with that user; returns any other id unchanged.
10
+ *
11
+ * chat.postMessage accepts a user id as `channel`, but Slack documents that the
12
+ * message then lands in the user's DM with Slackbot (USLACK), which the bot is
13
+ * not a member of. conversations.replies and chat.postMessage on the returned
14
+ * D id fail with channel_not_found, and human replies never reach the bot as
15
+ * message.im events. conversations.open returns the bot's own IM, which it can
16
+ * read, write, and receives events for.
17
+ */
18
+ export async function resolveSlackConversationId(
19
+ client: WebClient,
20
+ channelId: string,
21
+ ): Promise<string> {
22
+ if (!isSlackUserId(channelId)) return channelId;
23
+ const result = await client.conversations.open({ users: channelId });
24
+ const dmId = result.channel?.id;
25
+ if (!dmId) {
26
+ throw new Error(`conversations.open returned no DM channel for user ${channelId}`);
27
+ }
28
+ return dmId;
29
+ }
@@ -9,6 +9,12 @@
9
9
  import { createHash, randomBytes } from "node:crypto";
10
10
  import { type EventContext, TRIGGER_SURFACES, type TriggerSurface } from "./telemetry-contract";
11
11
  import catalog from "./telemetry-contract/catalog.json";
12
+ import {
13
+ COMPANY_ACQUISITION_SOURCES,
14
+ COMPANY_TEAM_SIZES,
15
+ COMPANY_USE_CASES,
16
+ USER_FUNCTIONS,
17
+ } from "./utils/company-profile";
12
18
 
13
19
  /** `org_` + 16 lowercase hex (self-host, minted here) or 27 alphanumerics (cloud). Same pattern the proxy enforces. */
14
20
  const ORG_ID_PATTERN = /^org_([0-9a-f]{16}|[A-Za-z0-9]{27})$/;
@@ -97,6 +103,9 @@ export interface ContextInput {
97
103
  installMethod?: string | null;
98
104
  installPreset?: string | null;
99
105
  acquisitionSource?: string | null;
106
+ teamSize?: string | null;
107
+ useCase?: string | null;
108
+ userFunction?: string | null;
100
109
  }
101
110
 
102
111
  /** Build the top-level `context` object of a schema_version 2 event. */
@@ -105,6 +114,11 @@ export function buildContext(input: ContextInput): EventContext {
105
114
  const orgName = input.orgName?.trim();
106
115
  const orgDomain = validOrgDomain(input.orgDomain);
107
116
  const orgWebsite = validOrgDomain(input.orgWebsite);
117
+ const teamSize = COMPANY_TEAM_SIZES.find((value) => value === input.teamSize);
118
+ const useCase = COMPANY_USE_CASES.find((value) => value === input.useCase);
119
+ const userFunction = userId
120
+ ? USER_FUNCTIONS.find((value) => value === input.userFunction)
121
+ : undefined;
108
122
  return {
109
123
  org_id: input.orgId,
110
124
  org_name: orgName ? orgName : null,
@@ -116,10 +130,14 @@ export function buildContext(input: ContextInput): EventContext {
116
130
  swarm_version: input.swarmVersion,
117
131
  install_method: input.installMethod ?? null,
118
132
  install_preset: input.installPreset ?? null,
119
- acquisition_source: input.acquisitionSource ?? null,
133
+ acquisition_source:
134
+ COMPANY_ACQUISITION_SOURCES.find((value) => value === input.acquisitionSource) ?? null,
120
135
  // Optional in the catalog: left out, not null, when unset, so an ingest
121
136
  // that predates the field keeps accepting events from installs without one.
122
137
  ...(orgWebsite ? { org_website: orgWebsite } : {}),
138
+ ...(teamSize ? { team_size: teamSize } : {}),
139
+ ...(useCase ? { use_case: useCase } : {}),
140
+ ...(userFunction ? { user_function: userFunction } : {}),
123
141
  };
124
142
  }
125
143
 
@@ -4,18 +4,48 @@
4
4
 
5
5
  Every event the ingest accepts with `schema_version: 2`. A v2 event that is not listed here, or that sends a property not listed for it, is rejected with a typed 400. `Emitter` is the envelope `source`.
6
6
 
7
+ ## `acquisition_source`
8
+
9
+ How the organization found Agent Swarm.
10
+
11
+ Values: `search`, `github`, `social`, `colleague`, `newsletter`, `event`, `ai_assistant`, `hacker_news`, `other`.
12
+
13
+ ## `notification_moment`
14
+
15
+ Moment that made the Slack Connect invite relevant.
16
+
17
+ Values: `task_failed`, `first_workflow`, `default`.
18
+
7
19
  ## `popup`
8
20
 
9
21
  Dashboard pop-up that a popup.* event is about.
10
22
 
11
23
  Values: `feedback`, `org_name`, `used_by`.
12
24
 
25
+ ## `team_size`
26
+
27
+ Size of the organization team.
28
+
29
+ Values: `1`, `2-10`, `11-50`, `51+`.
30
+
13
31
  ## `trigger_surface`
14
32
 
15
33
  Surface that started a chain of work: agent-swarm's AgentTaskSourceSchema values plus other.
16
34
 
17
35
  Values: `slack`, `ui`, `api`, `mcp`, `github`, `gitlab`, `linear`, `jira`, `agentmail`, `schedule`, `workflow`, `system`, `other`.
18
36
 
37
+ ## `use_case`
38
+
39
+ Primary use of the swarm.
40
+
41
+ Values: `features`, `bugs`, `review`, `ops`, `docs`, `data`.
42
+
43
+ ## `user_function`
44
+
45
+ Job function of a user, separate from the RBAC user_role.
46
+
47
+ Values: `engineer`, `eng_lead`, `founder`, `product`, `ops`, `other`.
48
+
19
49
  ## `agent-fs`
20
50
 
21
51
  | Event | Emitter | Since | Description | Properties |
@@ -44,12 +74,15 @@ Common properties, allowed on every event of this product:
44
74
  | `agent.registered` | api-server | 2026-09-30 | An agent registered or reconnected. | `capabilities` (array, required)<br>`isReconnect` (boolean, required)<br>`role` (string) |
45
75
  | `compaction.triggered` | worker | 2026-09-30 | The harness compacted a session context. | `compactTrigger` (string, required)<br>`contextTotalTokens` (integer, required)<br>`preCompactTokens` (integer, required) |
46
76
  | `feature.used` | ui | 2026-09-30 | A dashboard feature was used. | `feature` (string, required) |
47
- | `fleet_benchmark.viewed` | ui | 2026-10-12 | The fleet benchmark card was shown. | `has_org_name` (boolean, required) |
77
+ | `fleet_benchmark.unlocked` | ui | 2026-10-18 | An admin supplied the company profile fields for the full benchmark. | `fields` (array of website \| team_size \| use_case, required) |
78
+ | `fleet_benchmark.viewed` | ui | 2026-10-12 | The fleet benchmark card was shown. | `has_org_name` (boolean, required)<br>`level` (basic \| full) |
79
+ | `identity.lookup` | ui | 2026-10-18 | A dashboard identity lookup matched an existing user or found no match. | `matched` (boolean, required) |
80
+ | `identity.user_created` | ui | 2026-10-18 | A user created a dashboard identity. Email and personal names stay out of telemetry. | `email_kind` (work \| personal, required)<br>`has_company` (boolean, required)<br>`has_function` (boolean, required)<br>`surface` (identity_modal \| setup, required) |
48
81
  | `integration.connected` | api-server | 2026-09-30 | An integration was connected. | `first_of_type` (boolean, required)<br>`provider` (string)<br>`type` (string, required) |
49
82
  | `lead.captured` | api-server | 2026-09-30 | A consented lead (Teams waitlist or private-beta sign-up). The email stays in feedback_submissions. | `channel` (string, required)<br>`consent` (boolean, required)<br>`submission_id` (string, required) |
50
- | `notification.dismissed` | ui | 2026-09-30 | A notification-centre item was dismissed. | `key` (string, required) |
51
- | `notification.submitted` | ui | 2026-09-30 | A notification-centre item was submitted. | `email_domain` (string)<br>`key` (string, required) |
52
- | `notification.viewed` | ui | 2026-09-30 | A notification-centre item was shown. | `key` (string, required) |
83
+ | `notification.dismissed` | ui | 2026-09-30 | A notification-centre item was dismissed. | `key` (string, required)<br>`moment` (task_failed \| first_workflow \| default) |
84
+ | `notification.submitted` | ui | 2026-09-30 | A notification-centre item was submitted. | `email_domain` (string)<br>`key` (string, required)<br>`moment` (task_failed \| first_workflow \| default)<br>`user_function` (engineer \| eng_lead \| founder \| product \| ops \| other) |
85
+ | `notification.viewed` | ui | 2026-09-30 | A notification-centre item was shown. | `key` (string, required)<br>`moment` (task_failed \| first_workflow \| default) |
53
86
  | `onboarding.completed` | api-server | 2026-09-30 | Onboarding was completed. | `seconds_since_install` (integer)<br>`seconds_since_start` (integer, required) |
54
87
  | `onboarding.dismissed` | api-server | 2026-09-30 | Onboarding was dismissed. | `seconds_since_install` (integer)<br>`seconds_since_start` (integer, required) |
55
88
  | `onboarding.first_task_completed` | api-server | 2026-09-30 | The first task after onboarding completed. | `method` (string)<br>`seconds_since_install` (integer)<br>`seconds_since_start` (integer, required) |
@@ -58,12 +91,15 @@ Common properties, allowed on every event of this product:
58
91
  | `onboarding.step_failed` | api-server | 2026-09-30 | An onboarding step failed. | `error_class` (string, required)<br>`seconds_since_install` (integer)<br>`seconds_since_start` (integer, required)<br>`step` (string, required) |
59
92
  | `onboarding.step_skipped` | api-server | 2026-09-30 | An onboarding step was skipped. | `seconds_since_install` (integer)<br>`seconds_since_start` (integer, required)<br>`step` (string, required) |
60
93
  | `onboarding.step_viewed` | api-server | 2026-09-30 | An onboarding step was shown. | `seconds_since_install` (integer)<br>`seconds_since_start` (integer, required)<br>`step` (string, required) |
61
- | `org.profile_updated` | ui | 2026-10-12 | An admin changed the org profile. Lists which fields changed, never their values. | `fields` (array, required)<br>`surface` (prompt \| setup \| settings, required) |
94
+ | `org.profile_updated` | ui | 2026-10-12 | An admin changed the org profile. Lists which fields changed, never their values. | `fields` (array of name \| website \| team_size \| use_case \| acquisition_source, required)<br>`surface` (enum, required) |
62
95
  | `org.snapshot` | api-server | 2026-09-30 | Daily per-install user and agent counts. Counts only: no names, emails or IDs. | `agents_total` (integer ≥0, required)<br>`users_active_7d` (integer ≥0, required)<br>`users_admin` (integer ≥0, required)<br>`users_linked_github` (integer ≥0, required)<br>`users_linked_gitlab` (integer ≥0, required)<br>`users_linked_jira` (integer ≥0, required)<br>`users_linked_linear` (integer ≥0, required)<br>`users_linked_other` (integer ≥0, required)<br>`users_linked_slack` (integer ≥0, required)<br>`users_suspended` (integer ≥0, required)<br>`users_total` (integer ≥0, required)<br>`users_with_login` (integer ≥0, required) |
63
96
  | `page.viewed` | ui | 2026-09-30 | A dashboard page was viewed. | `route_template` (string, required) |
64
97
  | `popup.dismissed` | ui | 2026-10-12 | A dashboard pop-up was closed without submitting. | `method` (later \| close \| escape, required)<br>`popup` (feedback \| org_name \| used_by, required) |
65
98
  | `popup.shown` | ui | 2026-10-12 | A dashboard pop-up was shown. Telemetry-gated: never sent while telemetry is off. | `popup` (feedback \| org_name \| used_by, required)<br>`trigger` (task_failed \| tasks_completed \| workflow_completed \| quarterly \| missing_org_name, required) |
66
- | `popup.submitted` | ui | 2026-10-12 | A dashboard pop-up was submitted. Content stays out of telemetry: only flags for what was filled. | `has_contact` (boolean, required)<br>`has_message` (boolean, required)<br>`popup` (feedback \| org_name \| used_by, required)<br>`score` (integer ≥0) |
99
+ | `popup.submitted` | ui | 2026-10-12 | A dashboard pop-up was submitted. Content stays out of telemetry: only flags for what was filled. | `answered` (integer ≥0)<br>`has_contact` (boolean, required)<br>`has_message` (boolean, required)<br>`perks` (array of used_by \| slack_connect)<br>`popup` (feedback \| org_name \| used_by, required)<br>`score` (integer ≥0) |
100
+ | `ranking.opted_in` | api-server | 2026-10-18 | An admin opted the install into the public ranking, or the API rebuilt its listing after an org identity change. | `listing` (string, required) |
101
+ | `ranking.opted_out` | api-server | 2026-10-18 | The install left the public ranking: the admin turned it off, or the org name or website was cleared or changed. | `domain` (string, required) |
102
+ | `ranking.usage` | worker | 2026-10-18 | Token usage of one session on an install opted into the public ranking. Sent next to session.cost. | `cacheReadTokens` (integer ≥0)<br>`cacheWriteTokens` (integer ≥0)<br>`inputTokens` (integer ≥0, required)<br>`model` (string)<br>`outputTokens` (integer ≥0, required)<br>`provider` (string)<br>`totalTokens` (integer ≥0, required) |
67
103
  | `schedule.error` | api-server | 2026-09-30 | A schedule failed to fire. | `consecutiveErrors` (integer, required)<br>`scheduleType` (string, required)<br>`triggeredWorkflows` (boolean, required)<br>`wasRecovered` (boolean, required) |
68
104
  | `schedule.executed` | api-server | 2026-09-30 | A schedule fired. | `scheduleType` (string, required)<br>`triggeredWorkflows` (boolean, required)<br>`wasRecovered` (boolean, required) |
69
105
  | `server.shutdown` | api-server | 2026-09-30 | The API server shut down. | `sessionsProcessed` (integer, required)<br>`signal` (string, required)<br>`uptimeMs` (integer, required) |
@@ -74,6 +110,7 @@ Common properties, allowed on every event of this product:
74
110
  | `session.failure` | worker | 2026-09-30 | A session failed. | `agentId` (string, required)<br>`durationMs` (integer, required)<br>`errorCategory` (string, required)<br>`model` (string, required)<br>`provider` (string, required)<br>`taskId` (string, nullable, required)<br>`trigger_surface` (enum, nullable, required)<br>`wasRateLimited` (boolean, required) |
75
111
  | `session.started` | worker | 2026-09-30 | A worker or lead session started. | `agentId` (string, required)<br>`harnessProvider` (string, required)<br>`model` (string)<br>`role` (string, required)<br>`taskId` (string, nullable, required)<br>`trigger_surface` (enum, nullable, required) |
76
112
  | `session.steered` | api-server | 2026-09-30 | A running session received a steering message. | `by_kind` (string, required)<br>`trigger_surface` (enum, nullable, required) |
113
+ | `setup.worker_command_copied` | ui | 2026-10-18 | An admin copied a worker command from the setup health popover. | `harness` (enum, required)<br>`target` (compose \| docker \| kubernetes, required) |
77
114
  | `skill.invoked` | worker | 2026-09-30 | A skill was invoked in a session. | `skill_name` (string, required)<br>`skill_source` (string, required)<br>`trigger_surface` (enum, nullable, required) |
78
115
  | `task.cancelled` | api-server | 2026-09-30 | A task was cancelled. | `agentId` (string)<br>`durationMs` (integer)<br>`previousStatus` (string, required)<br>`taskId` (string, required)<br>`task_source` (enum, required)<br>`trigger_surface` (enum, required) |
79
116
  | `task.claimed` | api-server | 2026-09-30 | An agent claimed a task. | `agentId` (string, required)<br>`taskId` (string, required)<br>`task_source` (enum, required)<br>`trigger_surface` (enum, required) |
@@ -83,9 +120,9 @@ Common properties, allowed on every event of this product:
83
120
  | `task.session_completed` | worker | 2026-09-30 | A worker session for a task finished. | `agentId` (string, required)<br>`durationMs` (integer, required)<br>`exitCode` (integer, required)<br>`harnessVariant` (string)<br>`harnessVersion` (string)<br>`isError` (boolean, required)<br>`model` (string, required)<br>`provider` (string, required)<br>`taskId` (string, nullable, required)<br>`trigger_surface` (enum, nullable, required) |
84
121
  | `task.started` | api-server | 2026-09-30 | A task started running. | `agentId` (string, required)<br>`taskId` (string, required)<br>`task_source` (enum, required)<br>`trigger_surface` (enum, required) |
85
122
  | `task.superseded` | api-server | 2026-09-30 | A task was superseded by another task. | `agentId` (string)<br>`durationMs` (integer)<br>`harnessVariant` (string)<br>`harnessVersion` (string)<br>`provider` (string)<br>`reason` (string, required)<br>`taskId` (string, required)<br>`task_source` (enum, required)<br>`trigger_surface` (enum, required) |
86
- | `telemetry.enabled` | api-server | 2026-10-12 | Telemetry was turned on. Sent once, on the first boot or re-init after opting in. | `via` (banner \| settings \| env, required) |
123
+ | `telemetry.enabled` | api-server | 2026-10-12 | Telemetry was turned on. Sent once, on the first boot or re-init after opting in. | `via` (banner \| settings \| env \| benchmark, required) |
87
124
  | `ui.session_started` | ui | 2026-09-30 | A dashboard session started. | none |
88
- | `used_by.consent_changed` | ui | 2026-10-12 | An admin granted or revoked the "used by" logo consent. The request itself goes to /v1/used-by. | `granted` (boolean, required) |
125
+ | `used_by.consent_changed` | ui | 2026-10-12 | An admin granted or revoked the "used by" logo consent. The request itself goes to /v1/used-by. | `granted` (boolean, required)<br>`has_function` (boolean)<br>`has_quote` (boolean) |
89
126
  | `workflow.completed` | api-server | 2026-09-30 | A workflow run completed. | `durationMs` (integer)<br>`stepsCompleted` (integer, required)<br>`stepsFailed` (integer, required)<br>`workflowId` (string, required) |
90
127
  | `workflow.created` | api-server | 2026-09-30 | A workflow was created. | `nodeCount` (integer, required)<br>`via` (api \| mcp)<br>`workflowId` (string, required) |
91
128
  | `workflow.deleted` | api-server | 2026-09-30 | A workflow was deleted. | `via` (api \| mcp)<br>`workflowId` (string, required) |
@@ -1,9 +1,43 @@
1
1
  {
2
2
  "repo": "desplega-ai/proxy",
3
- "commit": "09ef0f38647e387d1e10485de5968ba047a2cef1",
3
+ "commit": "cc593585467a920dcb8731993d092639372dc7af",
4
4
  "files": {
5
- "types.gen.ts": "9de6741502759552556b4073a1ca30cd1fbae8cf349dda6754b4ed7d7f271097",
6
- "catalog.json": "b6dd31da171ac2545f311473f2b6cd306a03827870fa86472200aa938c044214",
7
- "EVENTS.md": "8ae820a977bba7f4cb3972aae1295cb6b12e1e5ee81d3ffed55606e213a66004"
5
+ "types.gen.ts": "aa8a682f1d875515d63cf5bd3fa667dcb06cd851f8b2b798482a4c71cd775444",
6
+ "catalog.json": "595654f288ae2a7cbb265b6b2a72392acc33f5acde365d72829101912525a891",
7
+ "EVENTS.md": "51ee5491c633d684b163d727a369a08b5c1d3f4ba453277d840526449a0bad0c",
8
+ "ranking/fixtures/expected.json": "6d506546f48d99a089666bed2a4c08752ebb63a029392c76ffd057e9520adc70",
9
+ "ranking/fixtures/invalid/bad-category.json": "a4c36da6079c36d15e5e8c8e6322fc97b172de015a80a26cee8cab699f666236",
10
+ "ranking/fixtures/invalid/bad-claim.json": "cee14d465545d057cfb61922301a5119187ba17d70efabb16528a5e305d7b065",
11
+ "ranking/fixtures/invalid/blank-description.json": "bf1ae1a834613b67b59f42c158e892448f23268b41f1c851653f25e4843a20b0",
12
+ "ranking/fixtures/invalid/blank-name.json": "7e2cc0156ac5f5d42342a99c38fe0f822b893784f17cdcfa371277c847d83a2e",
13
+ "ranking/fixtures/invalid/description-too-long.json": "c96ed93d014fbdac8c674ab8266d41bca83547d42a0d6dec53f275a0258d1adf",
14
+ "ranking/fixtures/invalid/domain-uppercase.json": "5a3cefdceddf7716d0b6300453a928e122e3ca8fa55493d48666701ca9853ebb",
15
+ "ranking/fixtures/invalid/domain-with-scheme.json": "389f6216e350c8b13f472658b15bc485693a0064cf837a5a66a3f74cef8f26c3",
16
+ "ranking/fixtures/invalid/domain-with-www.json": "b936fd61b21ad5f0219e739686372b16e4e97c2101f239ed3497bb73b0307205",
17
+ "ranking/fixtures/invalid/http-source-url.json": "dcab46205d9113864f31966affe74edb9a9ffe1b2fc9bfb3923997daa30cf651",
18
+ "ranking/fixtures/invalid/missing-description.json": "9a3a3a1104c9e1c3dea17d3a81be87dcd96188d64729e601ecc94848215aea49",
19
+ "ranking/fixtures/invalid/missing-version.json": "81b54c7cae034bd6327b981ec17609e926f5ee03465b589bc997c5ec9ddfc60b",
20
+ "ranking/fixtures/invalid/name-not-string.json": "46af1d97dbe77735a8020dd3c7ea1b67f71d8310cc065341b82173229d6f9487",
21
+ "ranking/fixtures/invalid/name-too-long.json": "8c07bce282182b8e0d9476a70a78863c708ce25d6cce3c994e29c0ec10972255",
22
+ "ranking/fixtures/invalid/not-object.json": "53bd6a73a22019f092e9e6e454936e8ba172201553f897f43f478f4946effaea",
23
+ "ranking/fixtures/invalid/null.json": "38e0b9de817f645c4bec37c0d4a3e58baecccb040f5718dc069a72c7385a0bed",
24
+ "ranking/fixtures/invalid/other-with-subcategory.json": "e5bdaf6982b5bf8fedf08b31c40232808f91884177a88cae5c6ab45489aec892",
25
+ "ranking/fixtures/invalid/oversize.json": "e57b2d8030a3b62b6621fcd81eb90959c22d190d4bfb5ee834086808249ddbe2",
26
+ "ranking/fixtures/invalid/short-claim.json": "051e789f8989b052173ab90a21d6358200f45cadfb729f36081c462ba9a8096b",
27
+ "ranking/fixtures/invalid/subcategory-other-category.json": "3d4ca6ce612ace116e382b08579ee451b2c1cbf93716cb01ad61489b7cecbcd8",
28
+ "ranking/fixtures/invalid/trailing-data.json": "ffb822a83c7a2bfb41c6fdfab375c11232db70e5063ace529a1e4cc7b6be44ff",
29
+ "ranking/fixtures/invalid/unknown-field.json": "c24c57f208523d4de535057a636de1fc5abcad329d514baabb180cbcfdd6a5b9",
30
+ "ranking/fixtures/invalid/unsupported-version.json": "32e5c26b9c646090a3e94822594b208d629e60796c00f964216859ee8d086dc7",
31
+ "ranking/fixtures/invalid/updated-at-not-date.json": "a03111ddc50bcfc818b30e977a4b94c566884b04322e1600e7f70a04c120d5c1",
32
+ "ranking/fixtures/invalid/updated-at-offset.json": "91b78160eb83da274bb3d93fbd812b72f2e648935a31fb5685b32037391e63fc",
33
+ "ranking/fixtures/invalid/wrong-case-field.json": "76c8a019d0aabdd1ca394f3ea552511a98b2458e7b850b75289f88a665682087",
34
+ "ranking/fixtures/valid/category-without-subcategory.json": "45c5b872aec232bdcba791e6ba1a7aba698c825f389e194a38e96ad141f56e5a",
35
+ "ranking/fixtures/valid/full.json": "d6d93c4a6159e814c3f089c69083df700fb19359f127ccd2b71529a058dfe5e9",
36
+ "ranking/fixtures/valid/minimal.json": "de6629d6ee2c4b67598abfc5ec7f6470a93dd9893b07e6e7c93d018cf5445593",
37
+ "ranking/fixtures/valid/no-claim.json": "fa5c08ec50c1b602f404cf36ce8b1c03d131111379d914699378dd448431cb84",
38
+ "ranking/fixtures/valid/padded-text.json": "db71248bf83bb1ffb639208ec467a0228e5c37f604299d09838ab25dc61986a3",
39
+ "ranking/fixtures/valid/unicode-name.json": "01a9d2cc8c5fec128af3eef35bf16696286f28636dac21b9dec107b28fddf743",
40
+ "ranking/listing.v1.schema.json": "f839b669abadb25e031515a5cc2abd3aa2024e85e6117cae83133fc9dfbb769d",
41
+ "ranking/taxonomy.json": "c6abe7e437635c9a3c1a82a3477a8757ba6c0cb7cbeae86c8c3d175fb37f402c"
8
42
  }
9
43
  }
@@ -27,6 +27,64 @@
27
27
  "org_name",
28
28
  "used_by"
29
29
  ]
30
+ },
31
+ "team_size": {
32
+ "type": "string",
33
+ "description": "Size of the organization team.",
34
+ "enum": [
35
+ "1",
36
+ "2-10",
37
+ "11-50",
38
+ "51+"
39
+ ]
40
+ },
41
+ "use_case": {
42
+ "type": "string",
43
+ "description": "Primary use of the swarm.",
44
+ "enum": [
45
+ "features",
46
+ "bugs",
47
+ "review",
48
+ "ops",
49
+ "docs",
50
+ "data"
51
+ ]
52
+ },
53
+ "acquisition_source": {
54
+ "type": "string",
55
+ "description": "How the organization found Agent Swarm.",
56
+ "enum": [
57
+ "search",
58
+ "github",
59
+ "social",
60
+ "colleague",
61
+ "newsletter",
62
+ "event",
63
+ "ai_assistant",
64
+ "hacker_news",
65
+ "other"
66
+ ]
67
+ },
68
+ "user_function": {
69
+ "type": "string",
70
+ "description": "Job function of a user, separate from the RBAC user_role.",
71
+ "enum": [
72
+ "engineer",
73
+ "eng_lead",
74
+ "founder",
75
+ "product",
76
+ "ops",
77
+ "other"
78
+ ]
79
+ },
80
+ "notification_moment": {
81
+ "type": "string",
82
+ "description": "Moment that made the Slack Connect invite relevant.",
83
+ "enum": [
84
+ "task_failed",
85
+ "first_workflow",
86
+ "default"
87
+ ]
30
88
  }
31
89
  },
32
90
  "common_properties": {
@@ -1125,6 +1183,9 @@
1125
1183
  "key": {
1126
1184
  "type": "string",
1127
1185
  "required": true
1186
+ },
1187
+ "moment": {
1188
+ "ref": "notification_moment"
1128
1189
  }
1129
1190
  }
1130
1191
  },
@@ -1138,6 +1199,9 @@
1138
1199
  "key": {
1139
1200
  "type": "string",
1140
1201
  "required": true
1202
+ },
1203
+ "moment": {
1204
+ "ref": "notification_moment"
1141
1205
  }
1142
1206
  }
1143
1207
  },
@@ -1155,6 +1219,12 @@
1155
1219
  "email_domain": {
1156
1220
  "type": "string",
1157
1221
  "description": "Domain of the email typed into the item, never the address."
1222
+ },
1223
+ "moment": {
1224
+ "ref": "notification_moment"
1225
+ },
1226
+ "user_function": {
1227
+ "ref": "user_function"
1158
1228
  }
1159
1229
  }
1160
1230
  },
@@ -1167,7 +1237,8 @@
1167
1237
  "properties": {
1168
1238
  "feature": {
1169
1239
  "type": "string",
1170
- "required": true
1240
+ "required": true,
1241
+ "description": "Feature identifier, including health_popover and kickoff_call_opened. Existing identifiers remain accepted."
1171
1242
  }
1172
1243
  }
1173
1244
  },
@@ -1222,7 +1293,8 @@
1222
1293
  "properties": {
1223
1294
  "channel": {
1224
1295
  "type": "string",
1225
- "required": true
1296
+ "required": true,
1297
+ "description": "Lead channel, including setup_help and fleet_report. Existing channels remain accepted."
1226
1298
  },
1227
1299
  "submission_id": {
1228
1300
  "type": "string",
@@ -1305,6 +1377,22 @@
1305
1377
  "type": "boolean",
1306
1378
  "required": true,
1307
1379
  "description": "A name or email was left. The values go to /v1/feedback, never here."
1380
+ },
1381
+ "answered": {
1382
+ "type": "integer",
1383
+ "minimum": 0,
1384
+ "description": "Number of profile follow-up questions answered, never their values."
1385
+ },
1386
+ "perks": {
1387
+ "type": "array",
1388
+ "items": {
1389
+ "type": "string",
1390
+ "enum": [
1391
+ "used_by",
1392
+ "slack_connect"
1393
+ ]
1394
+ },
1395
+ "description": "Perks the admin explicitly selected."
1308
1396
  }
1309
1397
  }
1310
1398
  },
@@ -1317,8 +1405,18 @@
1317
1405
  "properties": {
1318
1406
  "fields": {
1319
1407
  "type": "array",
1408
+ "items": {
1409
+ "type": "string",
1410
+ "enum": [
1411
+ "name",
1412
+ "website",
1413
+ "team_size",
1414
+ "use_case",
1415
+ "acquisition_source"
1416
+ ]
1417
+ },
1320
1418
  "required": true,
1321
- "description": "Changed field names: name, website."
1419
+ "description": "Changed profile field names, never their values."
1322
1420
  },
1323
1421
  "surface": {
1324
1422
  "type": "string",
@@ -1326,7 +1424,12 @@
1326
1424
  "enum": [
1327
1425
  "prompt",
1328
1426
  "setup",
1329
- "settings"
1427
+ "settings",
1428
+ "org_name_popup",
1429
+ "feedback",
1430
+ "fleet_benchmark",
1431
+ "telemetry_banner",
1432
+ "identity_modal"
1330
1433
  ],
1331
1434
  "description": "Where the change was made. Not trigger_surface: that key fills the raw_events.trigger_surface column."
1332
1435
  }
@@ -1342,6 +1445,12 @@
1342
1445
  "granted": {
1343
1446
  "type": "boolean",
1344
1447
  "required": true
1448
+ },
1449
+ "has_quote": {
1450
+ "type": "boolean"
1451
+ },
1452
+ "has_function": {
1453
+ "type": "boolean"
1345
1454
  }
1346
1455
  }
1347
1456
  },
@@ -1358,7 +1467,8 @@
1358
1467
  "enum": [
1359
1468
  "banner",
1360
1469
  "settings",
1361
- "env"
1470
+ "env",
1471
+ "benchmark"
1362
1472
  ]
1363
1473
  }
1364
1474
  }
@@ -1373,6 +1483,82 @@
1373
1483
  "has_org_name": {
1374
1484
  "type": "boolean",
1375
1485
  "required": true
1486
+ },
1487
+ "level": {
1488
+ "type": "string",
1489
+ "enum": [
1490
+ "basic",
1491
+ "full"
1492
+ ]
1493
+ }
1494
+ }
1495
+ },
1496
+ {
1497
+ "product": "agent-swarm",
1498
+ "event": "ranking.opted_in",
1499
+ "description": "An admin opted the install into the public ranking, or the API rebuilt its listing after an org identity change.",
1500
+ "since": "2026-10-18",
1501
+ "source": "api-server",
1502
+ "properties": {
1503
+ "listing": {
1504
+ "type": "string",
1505
+ "required": true,
1506
+ "description": "The stringified telemetry_ranking listing (contracts/telemetry/ranking/listing.v1.schema.json). The ingest also requires its name and domain to equal context.org_name and context.org_website."
1507
+ }
1508
+ }
1509
+ },
1510
+ {
1511
+ "product": "agent-swarm",
1512
+ "event": "ranking.opted_out",
1513
+ "description": "The install left the public ranking: the admin turned it off, or the org name or website was cleared or changed.",
1514
+ "since": "2026-10-18",
1515
+ "source": "api-server",
1516
+ "properties": {
1517
+ "domain": {
1518
+ "type": "string",
1519
+ "required": true,
1520
+ "description": "The listing domain that leaves the ranking: a lowercase hostname."
1521
+ }
1522
+ }
1523
+ },
1524
+ {
1525
+ "product": "agent-swarm",
1526
+ "event": "ranking.usage",
1527
+ "description": "Token usage of one session on an install opted into the public ranking. Sent next to session.cost.",
1528
+ "since": "2026-10-18",
1529
+ "source": "worker",
1530
+ "properties": {
1531
+ "totalTokens": {
1532
+ "type": "integer",
1533
+ "required": true,
1534
+ "minimum": 0,
1535
+ "description": "inputTokens + cacheReadTokens + cacheWriteTokens + outputTokens. The ranking sums this."
1536
+ },
1537
+ "inputTokens": {
1538
+ "type": "integer",
1539
+ "required": true,
1540
+ "minimum": 0
1541
+ },
1542
+ "outputTokens": {
1543
+ "type": "integer",
1544
+ "required": true,
1545
+ "minimum": 0
1546
+ },
1547
+ "cacheReadTokens": {
1548
+ "type": "integer",
1549
+ "minimum": 0
1550
+ },
1551
+ "cacheWriteTokens": {
1552
+ "type": "integer",
1553
+ "minimum": 0
1554
+ },
1555
+ "model": {
1556
+ "type": "string",
1557
+ "description": "The session's model, the same value as session.cost.model. Usage without it, or with a value the ranking does not accept, is shown as the model unknown."
1558
+ },
1559
+ "provider": {
1560
+ "type": "string",
1561
+ "description": "The session's provider, the same value as session.cost.provider. Missing means unknown."
1376
1562
  }
1377
1563
  }
1378
1564
  },
@@ -1485,6 +1671,109 @@
1485
1671
  "required": true
1486
1672
  }
1487
1673
  }
1674
+ },
1675
+ {
1676
+ "product": "agent-swarm",
1677
+ "event": "identity.lookup",
1678
+ "description": "A dashboard identity lookup matched an existing user or found no match.",
1679
+ "since": "2026-10-18",
1680
+ "source": "ui",
1681
+ "properties": {
1682
+ "matched": {
1683
+ "type": "boolean",
1684
+ "required": true
1685
+ }
1686
+ }
1687
+ },
1688
+ {
1689
+ "product": "agent-swarm",
1690
+ "event": "identity.user_created",
1691
+ "description": "A user created a dashboard identity. Email and personal names stay out of telemetry.",
1692
+ "since": "2026-10-18",
1693
+ "source": "ui",
1694
+ "properties": {
1695
+ "surface": {
1696
+ "type": "string",
1697
+ "required": true,
1698
+ "enum": [
1699
+ "identity_modal",
1700
+ "setup"
1701
+ ]
1702
+ },
1703
+ "email_kind": {
1704
+ "type": "string",
1705
+ "required": true,
1706
+ "enum": [
1707
+ "work",
1708
+ "personal"
1709
+ ]
1710
+ },
1711
+ "has_function": {
1712
+ "type": "boolean",
1713
+ "required": true
1714
+ },
1715
+ "has_company": {
1716
+ "type": "boolean",
1717
+ "required": true
1718
+ }
1719
+ }
1720
+ },
1721
+ {
1722
+ "product": "agent-swarm",
1723
+ "event": "fleet_benchmark.unlocked",
1724
+ "description": "An admin supplied the company profile fields for the full benchmark.",
1725
+ "since": "2026-10-18",
1726
+ "source": "ui",
1727
+ "properties": {
1728
+ "fields": {
1729
+ "type": "array",
1730
+ "items": {
1731
+ "type": "string",
1732
+ "enum": [
1733
+ "website",
1734
+ "team_size",
1735
+ "use_case"
1736
+ ]
1737
+ },
1738
+ "required": true,
1739
+ "description": "Profile fields supplied, never their values."
1740
+ }
1741
+ }
1742
+ },
1743
+ {
1744
+ "product": "agent-swarm",
1745
+ "event": "setup.worker_command_copied",
1746
+ "description": "An admin copied a worker command from the setup health popover.",
1747
+ "since": "2026-10-18",
1748
+ "source": "ui",
1749
+ "properties": {
1750
+ "target": {
1751
+ "type": "string",
1752
+ "required": true,
1753
+ "enum": [
1754
+ "compose",
1755
+ "docker",
1756
+ "kubernetes"
1757
+ ]
1758
+ },
1759
+ "harness": {
1760
+ "type": "string",
1761
+ "required": true,
1762
+ "enum": [
1763
+ "claude",
1764
+ "codex",
1765
+ "pi",
1766
+ "devin",
1767
+ "claude-managed",
1768
+ "opencode",
1769
+ "acp",
1770
+ "dsh",
1771
+ "amp",
1772
+ "cursor",
1773
+ "grok"
1774
+ ]
1775
+ }
1776
+ }
1488
1777
  }
1489
1778
  ]
1490
1779
  }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$comment": "Every file in valid/ must parse in the proxy (ParseListing) and in agent-swarm (parseTelemetryRanking). Every file in invalid/ must fail in both; the value is the field the proxy names in its invalid_property message. A file's exact bytes are the listing string.",
3
+ "invalid": {
4
+ "bad-claim.json": "listing.claim",
5
+ "short-claim.json": "listing.claim",
6
+ "missing-description.json": "listing.description",
7
+ "unknown-field.json": "listing.logo",
8
+ "wrong-case-field.json": "listing.Claim",
9
+ "unsupported-version.json": "listing.v",
10
+ "missing-version.json": "listing.v",
11
+ "bad-category.json": "listing.category",
12
+ "subcategory-other-category.json": "listing.subcategory",
13
+ "other-with-subcategory.json": "listing.subcategory",
14
+ "http-source-url.json": "listing.sourceCodeUrl",
15
+ "domain-with-scheme.json": "listing.domain",
16
+ "domain-with-www.json": "listing.domain",
17
+ "domain-uppercase.json": "listing.domain",
18
+ "name-too-long.json": "listing.name",
19
+ "blank-name.json": "listing.name",
20
+ "blank-description.json": "listing.description",
21
+ "description-too-long.json": "listing.description",
22
+ "name-not-string.json": "listing.name",
23
+ "updated-at-offset.json": "listing.updatedAt",
24
+ "updated-at-not-date.json": "listing.updatedAt",
25
+ "not-object.json": "listing",
26
+ "null.json": "listing",
27
+ "trailing-data.json": "listing",
28
+ "oversize.json": "listing"
29
+ }
30
+ }