agent-tower 0.5.3 → 0.5.4-beta.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 (312) hide show
  1. package/README.md +6 -1
  2. package/dist/app.d.ts.map +1 -1
  3. package/dist/app.js +15 -1
  4. package/dist/app.js.map +1 -1
  5. package/dist/app.test.js +12 -0
  6. package/dist/app.test.js.map +1 -1
  7. package/dist/cli.js +18 -1
  8. package/dist/cli.js.map +1 -1
  9. package/dist/core/event-bus.d.ts +3 -0
  10. package/dist/core/event-bus.d.ts.map +1 -1
  11. package/dist/core/event-bus.js.map +1 -1
  12. package/dist/executors/__tests__/base.executor.test.js +29 -1
  13. package/dist/executors/__tests__/base.executor.test.js.map +1 -1
  14. package/dist/executors/__tests__/codex.executor.test.js +13 -0
  15. package/dist/executors/__tests__/codex.executor.test.js.map +1 -1
  16. package/dist/executors/base.executor.d.ts.map +1 -1
  17. package/dist/executors/base.executor.js +4 -0
  18. package/dist/executors/base.executor.js.map +1 -1
  19. package/dist/executors/execution-env.d.ts +1 -1
  20. package/dist/executors/execution-env.d.ts.map +1 -1
  21. package/dist/executors/execution-env.js +7 -0
  22. package/dist/executors/execution-env.js.map +1 -1
  23. package/dist/index.js +2 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp/http-client.d.ts +33 -1
  26. package/dist/mcp/http-client.d.ts.map +1 -1
  27. package/dist/mcp/http-client.js +21 -2
  28. package/dist/mcp/http-client.js.map +1 -1
  29. package/dist/mcp/index.js +4 -1
  30. package/dist/mcp/index.js.map +1 -1
  31. package/dist/mcp/server.d.ts +3 -1
  32. package/dist/mcp/server.d.ts.map +1 -1
  33. package/dist/mcp/server.js +64 -9
  34. package/dist/mcp/server.js.map +1 -1
  35. package/dist/mcp/tools/__tests__/workspaces.test.d.ts +2 -0
  36. package/dist/mcp/tools/__tests__/workspaces.test.d.ts.map +1 -0
  37. package/dist/mcp/tools/__tests__/workspaces.test.js +72 -0
  38. package/dist/mcp/tools/__tests__/workspaces.test.js.map +1 -0
  39. package/dist/mcp/tools/workspaces.d.ts +9 -1
  40. package/dist/mcp/tools/workspaces.d.ts.map +1 -1
  41. package/dist/mcp/tools/workspaces.js +96 -2
  42. package/dist/mcp/tools/workspaces.js.map +1 -1
  43. package/dist/mcp/types.d.ts +46 -0
  44. package/dist/mcp/types.d.ts.map +1 -1
  45. package/dist/mcp/types.js +23 -0
  46. package/dist/mcp/types.js.map +1 -1
  47. package/dist/middleware/__tests__/access-auth.test.d.ts +2 -0
  48. package/dist/middleware/__tests__/access-auth.test.d.ts.map +1 -0
  49. package/dist/middleware/__tests__/access-auth.test.js +249 -0
  50. package/dist/middleware/__tests__/access-auth.test.js.map +1 -0
  51. package/dist/middleware/access-auth.d.ts +3 -0
  52. package/dist/middleware/access-auth.d.ts.map +1 -0
  53. package/dist/middleware/access-auth.js +110 -0
  54. package/dist/middleware/access-auth.js.map +1 -0
  55. package/dist/routes/__tests__/files.test.d.ts +2 -0
  56. package/dist/routes/__tests__/files.test.d.ts.map +1 -0
  57. package/dist/routes/__tests__/files.test.js +101 -0
  58. package/dist/routes/__tests__/files.test.js.map +1 -0
  59. package/dist/routes/__tests__/previews.integration.test.d.ts +2 -0
  60. package/dist/routes/__tests__/previews.integration.test.d.ts.map +1 -0
  61. package/dist/routes/__tests__/previews.integration.test.js +269 -0
  62. package/dist/routes/__tests__/previews.integration.test.js.map +1 -0
  63. package/dist/routes/__tests__/previews.test.js +103 -1
  64. package/dist/routes/__tests__/previews.test.js.map +1 -1
  65. package/dist/routes/__tests__/team-runs-merge.test.d.ts +2 -0
  66. package/dist/routes/__tests__/team-runs-merge.test.d.ts.map +1 -0
  67. package/dist/routes/__tests__/team-runs-merge.test.js +156 -0
  68. package/dist/routes/__tests__/team-runs-merge.test.js.map +1 -0
  69. package/dist/routes/__tests__/team-runs-private-messages.test.d.ts +2 -0
  70. package/dist/routes/__tests__/team-runs-private-messages.test.d.ts.map +1 -0
  71. package/dist/routes/__tests__/team-runs-private-messages.test.js +82 -0
  72. package/dist/routes/__tests__/team-runs-private-messages.test.js.map +1 -0
  73. package/dist/routes/access-auth.d.ts +3 -0
  74. package/dist/routes/access-auth.d.ts.map +1 -0
  75. package/dist/routes/access-auth.js +89 -0
  76. package/dist/routes/access-auth.js.map +1 -0
  77. package/dist/routes/files.d.ts.map +1 -1
  78. package/dist/routes/files.js +46 -0
  79. package/dist/routes/files.js.map +1 -1
  80. package/dist/routes/index.d.ts.map +1 -1
  81. package/dist/routes/index.js +3 -0
  82. package/dist/routes/index.js.map +1 -1
  83. package/dist/routes/previews.d.ts +7 -2
  84. package/dist/routes/previews.d.ts.map +1 -1
  85. package/dist/routes/previews.js +106 -32
  86. package/dist/routes/previews.js.map +1 -1
  87. package/dist/routes/projects.d.ts.map +1 -1
  88. package/dist/routes/projects.js +9 -0
  89. package/dist/routes/projects.js.map +1 -1
  90. package/dist/routes/team-runs.d.ts +2 -0
  91. package/dist/routes/team-runs.d.ts.map +1 -1
  92. package/dist/routes/team-runs.js +48 -1
  93. package/dist/routes/team-runs.js.map +1 -1
  94. package/dist/routes/workspaces.d.ts.map +1 -1
  95. package/dist/routes/workspaces.js +43 -4
  96. package/dist/routes/workspaces.js.map +1 -1
  97. package/dist/services/__tests__/access-auth.service.test.d.ts +2 -0
  98. package/dist/services/__tests__/access-auth.service.test.d.ts.map +1 -0
  99. package/dist/services/__tests__/access-auth.service.test.js +316 -0
  100. package/dist/services/__tests__/access-auth.service.test.js.map +1 -0
  101. package/dist/services/__tests__/member-heartbeat.test.d.ts +2 -0
  102. package/dist/services/__tests__/member-heartbeat.test.d.ts.map +1 -0
  103. package/dist/services/__tests__/member-heartbeat.test.js +344 -0
  104. package/dist/services/__tests__/member-heartbeat.test.js.map +1 -0
  105. package/dist/services/__tests__/project.service.test.js +29 -0
  106. package/dist/services/__tests__/project.service.test.js.map +1 -1
  107. package/dist/services/__tests__/session-manager.team-run.test.js +144 -0
  108. package/dist/services/__tests__/session-manager.team-run.test.js.map +1 -1
  109. package/dist/services/__tests__/task.service.test.js +34 -0
  110. package/dist/services/__tests__/task.service.test.js.map +1 -1
  111. package/dist/services/__tests__/team-reconciler.service.test.js +307 -11
  112. package/dist/services/__tests__/team-reconciler.service.test.js.map +1 -1
  113. package/dist/services/__tests__/team-run.service.test.js +368 -2
  114. package/dist/services/__tests__/team-run.service.test.js.map +1 -1
  115. package/dist/services/__tests__/team-scheduler.service.test.js +409 -5
  116. package/dist/services/__tests__/team-scheduler.service.test.js.map +1 -1
  117. package/dist/services/__tests__/workspace.service.test.js +991 -3
  118. package/dist/services/__tests__/workspace.service.test.js.map +1 -1
  119. package/dist/services/access-auth.service.d.ts +82 -0
  120. package/dist/services/access-auth.service.d.ts.map +1 -0
  121. package/dist/services/access-auth.service.js +385 -0
  122. package/dist/services/access-auth.service.js.map +1 -0
  123. package/dist/services/mcp-config.service.d.ts.map +1 -1
  124. package/dist/services/mcp-config.service.js +8 -2
  125. package/dist/services/mcp-config.service.js.map +1 -1
  126. package/dist/services/mcp-config.service.test.js +18 -3
  127. package/dist/services/mcp-config.service.test.js.map +1 -1
  128. package/dist/services/member-heartbeat-scheduler.d.ts +33 -0
  129. package/dist/services/member-heartbeat-scheduler.d.ts.map +1 -0
  130. package/dist/services/member-heartbeat-scheduler.js +83 -0
  131. package/dist/services/member-heartbeat-scheduler.js.map +1 -0
  132. package/dist/services/project-guards.d.ts +5 -0
  133. package/dist/services/project-guards.d.ts.map +1 -1
  134. package/dist/services/project-guards.js +47 -0
  135. package/dist/services/project-guards.js.map +1 -1
  136. package/dist/services/project.service.d.ts +6 -4
  137. package/dist/services/project.service.d.ts.map +1 -1
  138. package/dist/services/project.service.js +16 -7
  139. package/dist/services/project.service.js.map +1 -1
  140. package/dist/services/session-manager.d.ts +11 -0
  141. package/dist/services/session-manager.d.ts.map +1 -1
  142. package/dist/services/session-manager.js +76 -0
  143. package/dist/services/session-manager.js.map +1 -1
  144. package/dist/services/task.service.d.ts +11 -9
  145. package/dist/services/task.service.d.ts.map +1 -1
  146. package/dist/services/task.service.js +17 -12
  147. package/dist/services/task.service.js.map +1 -1
  148. package/dist/services/team-reconciler.service.d.ts +39 -0
  149. package/dist/services/team-reconciler.service.d.ts.map +1 -1
  150. package/dist/services/team-reconciler.service.js +234 -3
  151. package/dist/services/team-reconciler.service.js.map +1 -1
  152. package/dist/services/team-run.service.d.ts +7 -1
  153. package/dist/services/team-run.service.d.ts.map +1 -1
  154. package/dist/services/team-run.service.js +98 -9
  155. package/dist/services/team-run.service.js.map +1 -1
  156. package/dist/services/team-scheduler.service.d.ts +21 -1
  157. package/dist/services/team-scheduler.service.d.ts.map +1 -1
  158. package/dist/services/team-scheduler.service.js +252 -15
  159. package/dist/services/team-scheduler.service.js.map +1 -1
  160. package/dist/services/terminal-manager.d.ts.map +1 -1
  161. package/dist/services/terminal-manager.js +1 -0
  162. package/dist/services/terminal-manager.js.map +1 -1
  163. package/dist/services/workspace.service.d.ts +56 -1
  164. package/dist/services/workspace.service.d.ts.map +1 -1
  165. package/dist/services/workspace.service.js +841 -8
  166. package/dist/services/workspace.service.js.map +1 -1
  167. package/dist/socket/__tests__/socket-gateway.test.d.ts +2 -0
  168. package/dist/socket/__tests__/socket-gateway.test.d.ts.map +1 -0
  169. package/dist/socket/__tests__/socket-gateway.test.js +119 -0
  170. package/dist/socket/__tests__/socket-gateway.test.js.map +1 -0
  171. package/dist/socket/middleware/__tests__/auth.test.js +102 -2
  172. package/dist/socket/middleware/__tests__/auth.test.js.map +1 -1
  173. package/dist/socket/middleware/auth.d.ts +1 -0
  174. package/dist/socket/middleware/auth.d.ts.map +1 -1
  175. package/dist/socket/middleware/auth.js +22 -2
  176. package/dist/socket/middleware/auth.js.map +1 -1
  177. package/dist/socket/socket-gateway.d.ts +6 -2
  178. package/dist/socket/socket-gateway.d.ts.map +1 -1
  179. package/dist/socket/socket-gateway.js +78 -15
  180. package/dist/socket/socket-gateway.js.map +1 -1
  181. package/dist/utils/internal-api-token.d.ts +9 -0
  182. package/dist/utils/internal-api-token.d.ts.map +1 -0
  183. package/dist/utils/internal-api-token.js +74 -0
  184. package/dist/utils/internal-api-token.js.map +1 -0
  185. package/dist/utils/preview-path.d.ts +11 -0
  186. package/dist/utils/preview-path.d.ts.map +1 -0
  187. package/dist/utils/preview-path.js +46 -0
  188. package/dist/utils/preview-path.js.map +1 -0
  189. package/dist/utils/process-launch.test.js +14 -0
  190. package/dist/utils/process-launch.test.js.map +1 -1
  191. package/dist/web/assets/{AgentDemoPage-DMLw4xpg.js → AgentDemoPage-UmBBXiZq.js} +1 -1
  192. package/dist/web/assets/{AgentEnvironmentSettingsPage-NgRdouLu.js → AgentEnvironmentSettingsPage-DeMVC_O2.js} +1 -1
  193. package/dist/web/assets/{AgentLogo-ThhvSi7G.js → AgentLogo-sxp-yGLB.js} +1 -1
  194. package/dist/web/assets/{ConversationPage-B1ZcyF_h.js → ConversationPage-ykUuKcMG.js} +2 -2
  195. package/dist/web/assets/CreateTaskInput-WmNhRnVp.js +1 -0
  196. package/dist/web/assets/{DemoPage-CN2OBKzu.js → DemoPage-Cx-F46PV.js} +3 -3
  197. package/dist/web/assets/GeneralSettingsPage-DM4iy6dp.js +1 -0
  198. package/dist/web/assets/{Icons-DIZBOtuC.js → Icons-CO02_BMI.js} +1 -1
  199. package/dist/web/assets/{LoadingPreviewPage-CRBcypeY.js → LoadingPreviewPage-C58uR8H7.js} +1 -1
  200. package/dist/web/assets/McpSettingsPage-CTe-SNfY.js +1 -0
  201. package/dist/web/assets/{MemberAvatar-Y_pJlw-N.js → MemberAvatar-CZegYpYl.js} +1 -1
  202. package/dist/web/assets/NotificationSettingsPage-D17SAmMK.js +1 -0
  203. package/dist/web/assets/ProfileSettingsPage-B2rHV2eU.js +3 -0
  204. package/dist/web/assets/{ProjectKanbanPage-CBfocvKp.js → ProjectKanbanPage-SpCqpcZ0.js} +31 -32
  205. package/dist/web/assets/ProjectSettingsPage-2dD_ahm-.js +2 -0
  206. package/dist/web/assets/{ProviderSettingsPage-D-1Fyh5B.js → ProviderSettingsPage-D9vu3rO0.js} +6 -6
  207. package/dist/web/assets/{SettingsMasterDetail-CZfVaFo2.js → SettingsMasterDetail-CwRB1WBt.js} +1 -1
  208. package/dist/web/assets/{TeamSettingsPage-DysTmOGE.js → TeamSettingsPage-QXwc1AJE.js} +1 -1
  209. package/dist/web/assets/{arc-CgLBAHTH.js → arc-BRCC5BeU.js} +1 -1
  210. package/dist/web/assets/{architectureDiagram-3BPJPVTR-CP9eQfdk.js → architectureDiagram-3BPJPVTR-7lTGsSu5.js} +1 -1
  211. package/dist/web/assets/{arrow-left-y1LwO7sB.js → arrow-left-CNgpy5r6.js} +1 -1
  212. package/dist/web/assets/{blockDiagram-GPEHLZMM-BURZnUwn.js → blockDiagram-GPEHLZMM-CnscyQkX.js} +1 -1
  213. package/dist/web/assets/{c4Diagram-AAUBKEIU-Dzgp3z3S.js → c4Diagram-AAUBKEIU-DDhuPTLZ.js} +1 -1
  214. package/dist/web/assets/channel-S-3oxkZZ.js +1 -0
  215. package/dist/web/assets/check-DRdZLPss.js +1 -0
  216. package/dist/web/assets/{chevron-down--B7iZqBL.js → chevron-down-CqZBsPeR.js} +1 -1
  217. package/dist/web/assets/{chevron-right-7PShDIwg.js → chevron-right-YWciNkox.js} +1 -1
  218. package/dist/web/assets/{chevron-up-3n_vHdrD.js → chevron-up-BJ4i5iAn.js} +1 -1
  219. package/dist/web/assets/{chunk-2J33WTMH-CIpasa01.js → chunk-2J33WTMH-B96XJhZG.js} +1 -1
  220. package/dist/web/assets/{chunk-4BX2VUAB-DeSe2m1y.js → chunk-4BX2VUAB-IUZUHtbw.js} +1 -1
  221. package/dist/web/assets/{chunk-55IACEB6-BkJ6ogdn.js → chunk-55IACEB6-DcO4xSOO.js} +1 -1
  222. package/dist/web/assets/{chunk-727SXJPM-Bkbv-knP.js → chunk-727SXJPM-DuQwKkk-.js} +1 -1
  223. package/dist/web/assets/{chunk-AQP2D5EJ-BG9wGFIo.js → chunk-AQP2D5EJ-QotCqjAo.js} +1 -1
  224. package/dist/web/assets/{chunk-FMBD7UC4-Cvl_2za9.js → chunk-FMBD7UC4-C7hUbfZh.js} +1 -1
  225. package/dist/web/assets/{chunk-ND2GUHAM-B_zdzkWX.js → chunk-ND2GUHAM-B_C5eChQ.js} +1 -1
  226. package/dist/web/assets/{chunk-QZHKN3VN-Ch6dvKNw.js → chunk-QZHKN3VN-DRgZY4LJ.js} +1 -1
  227. package/dist/web/assets/{circle-alert-W13JkYj3.js → circle-alert-Ch4pQ3zT.js} +1 -1
  228. package/dist/web/assets/classDiagram-4FO5ZUOK-C00aPgpD.js +1 -0
  229. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-C00aPgpD.js +1 -0
  230. package/dist/web/assets/{code-block-OCS4YCEC-CYhJ9OPu.js → code-block-OCS4YCEC-h5zD4EvJ.js} +1 -1
  231. package/dist/web/assets/confirm-dialog-DG0L1v-9.js +1 -0
  232. package/dist/web/assets/{copy-bJ2sut_L.js → copy-JHS-5tjr.js} +1 -1
  233. package/dist/web/assets/{cose-bilkent-S5V4N54A-DWlnxyfH.js → cose-bilkent-S5V4N54A-6Gv8U8Cj.js} +1 -1
  234. package/dist/web/assets/{dagre-BM42HDAG-Bt3QI02a.js → dagre-BM42HDAG-Cf4rsmyS.js} +1 -1
  235. package/dist/web/assets/{diagram-2AECGRRQ-EaJBYSnS.js → diagram-2AECGRRQ-DW3DQ8NA.js} +1 -1
  236. package/dist/web/assets/{diagram-5GNKFQAL-BGyRb-_h.js → diagram-5GNKFQAL-C5cQ_MTX.js} +1 -1
  237. package/dist/web/assets/{diagram-KO2AKTUF-CZhDTMfm.js → diagram-KO2AKTUF-Dcs4NTfn.js} +1 -1
  238. package/dist/web/assets/{diagram-LMA3HP47-Be8BAxmL.js → diagram-LMA3HP47-lLI-OolH.js} +1 -1
  239. package/dist/web/assets/{diagram-OG6HWLK6-DEdQ7Cml.js → diagram-OG6HWLK6-BTdMG1u6.js} +1 -1
  240. package/dist/web/assets/{erDiagram-TEJ5UH35-CG9SNlbz.js → erDiagram-TEJ5UH35-BrKfSMWb.js} +1 -1
  241. package/dist/web/assets/{flowDiagram-I6XJVG4X-BUpx5PVX.js → flowDiagram-I6XJVG4X-BFT9EHqo.js} +1 -1
  242. package/dist/web/assets/folder-picker--V79noua.js +1 -0
  243. package/dist/web/assets/{ganttDiagram-6RSMTGT7-D7vRxMpE.js → ganttDiagram-6RSMTGT7-D_44EJ_y.js} +1 -1
  244. package/dist/web/assets/{gitGraphDiagram-PVQCEYII-3lhH-RcD.js → gitGraphDiagram-PVQCEYII-COrCr27e.js} +1 -1
  245. package/dist/web/assets/index-BC5stA77.js +122 -0
  246. package/dist/web/assets/{index-CGMjRoF7.js → index-Cjaho2ST.js} +4 -4
  247. package/dist/web/assets/index-DRJLGAPR.css +1 -0
  248. package/dist/web/assets/{infoDiagram-5YYISTIA-C5SNbJpO.js → infoDiagram-5YYISTIA-Derwhgw-.js} +1 -1
  249. package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-Ca7tX9_0.js → ishikawaDiagram-YF4QCWOH-Dv_SKfKy.js} +1 -1
  250. package/dist/web/assets/{journeyDiagram-JHISSGLW-B2oo6nxY.js → journeyDiagram-JHISSGLW-BvL0Myto.js} +1 -1
  251. package/dist/web/assets/{kanban-definition-UN3LZRKU-D1CzIzX9.js → kanban-definition-UN3LZRKU-D9iCCF7g.js} +1 -1
  252. package/dist/web/assets/{layers-BbLzQqyy.js → layers-D-OLv40U.js} +1 -1
  253. package/dist/web/assets/{linear-BWowtcGw.js → linear-DLebIyPZ.js} +1 -1
  254. package/dist/web/assets/{mermaid-NOHMQCX5-B42ziicV.js → mermaid-NOHMQCX5-CyA4Kmm7.js} +40 -40
  255. package/dist/web/assets/{message-square-Bd_m34OX.js → message-square-ByVmnBN0.js} +1 -1
  256. package/dist/web/assets/{mindmap-definition-RKZ34NQL-CYbO6QCk.js → mindmap-definition-RKZ34NQL-CJXkujXD.js} +1 -1
  257. package/dist/web/assets/{modal-CxOKWOjZ.js → modal-KKPLseLk.js} +1 -1
  258. package/dist/web/assets/{pencil-h5kxwbcu.js → pencil-B7ylaB7k.js} +1 -1
  259. package/dist/web/assets/{pieDiagram-4H26LBE5-DXQghKRy.js → pieDiagram-4H26LBE5-C8DfXjYu.js} +1 -1
  260. package/dist/web/assets/{quadrantDiagram-W4KKPZXB-C6lAMMQB.js → quadrantDiagram-W4KKPZXB-BxaUhA-J.js} +1 -1
  261. package/dist/web/assets/{requirementDiagram-4Y6WPE33-Di9Le7Wy.js → requirementDiagram-4Y6WPE33-CkP381y3.js} +1 -1
  262. package/dist/web/assets/{sankeyDiagram-5OEKKPKP-BGpnptvR.js → sankeyDiagram-5OEKKPKP-Ciot-1f1.js} +1 -1
  263. package/dist/web/assets/{select-DFuN9DX8.js → select-CLvHC1t4.js} +1 -1
  264. package/dist/web/assets/{sequenceDiagram-3UESZ5HK-DjfkfaQL.js → sequenceDiagram-3UESZ5HK-ZrO6aulq.js} +1 -1
  265. package/dist/web/assets/{stateDiagram-AJRCARHV-DsELotm9.js → stateDiagram-AJRCARHV-BDC3J_xT.js} +1 -1
  266. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-C_4zupNH.js +1 -0
  267. package/dist/web/assets/{switch-gL7lBFj6.js → switch-DqXAu8pW.js} +1 -1
  268. package/dist/web/assets/{textarea-Lr4GZaYW.js → textarea-ByV2n54w.js} +1 -1
  269. package/dist/web/assets/{timeline-definition-PNZ67QCA-Cq1BWC0T.js → timeline-definition-PNZ67QCA-CG898aCW.js} +1 -1
  270. package/dist/web/assets/{trash-2-B7GFt5Wl.js → trash-2-D-MBxpK4.js} +1 -1
  271. package/dist/web/assets/{upload-L8hpDFoO.js → upload-CkkorsYk.js} +1 -1
  272. package/dist/web/assets/{use-profiles-zIsoigD8.js → use-profiles-B62R9Kbn.js} +1 -1
  273. package/dist/web/assets/use-projects-JMhtZFd6.js +1 -0
  274. package/dist/web/assets/{use-providers-erJ2iHLz.js → use-providers-Cg1RDnUJ.js} +1 -1
  275. package/dist/web/assets/{useNormalizedLogs-CXAn7xj_.js → useNormalizedLogs-BMa5-cCl.js} +1 -1
  276. package/dist/web/assets/{vennDiagram-CIIHVFJN-DdOfNtRo.js → vennDiagram-CIIHVFJN-CNRNbGoo.js} +1 -1
  277. package/dist/web/assets/{wardley-L42UT6IY-BeKcEIgK.js → wardley-L42UT6IY-Fm0b_w6O.js} +1 -1
  278. package/dist/web/assets/{wardleyDiagram-YWT4CUSO-DPKOxABd.js → wardleyDiagram-YWT4CUSO-C_xf1EWg.js} +1 -1
  279. package/dist/web/assets/{xychartDiagram-2RQKCTM6-olIy_aaY.js → xychartDiagram-2RQKCTM6-D9yke6dF.js} +1 -1
  280. package/dist/web/index.html +2 -2
  281. package/node_modules/@agent-tower/shared/dist/types.d.ts +198 -1
  282. package/node_modules/@agent-tower/shared/dist/types.d.ts.map +1 -1
  283. package/node_modules/@agent-tower/shared/dist/types.js.map +1 -1
  284. package/node_modules/@prisma/client/.prisma/client/edge.js +52 -5
  285. package/node_modules/@prisma/client/.prisma/client/index-browser.js +47 -0
  286. package/node_modules/@prisma/client/.prisma/client/index.d.ts +6144 -2196
  287. package/node_modules/@prisma/client/.prisma/client/index.js +52 -5
  288. package/node_modules/@prisma/client/.prisma/client/package.json +1 -1
  289. package/node_modules/@prisma/client/.prisma/client/schema.prisma +94 -30
  290. package/node_modules/@prisma/client/.prisma/client/wasm.js +47 -0
  291. package/package.json +1 -1
  292. package/prisma/migrations/20260618010000_add_workspace_verdicts/migration.sql +27 -0
  293. package/prisma/migrations/20260701000000_add_access_auth_settings/migration.sql +9 -0
  294. package/prisma/migrations/20260702000000_add_teamrun_target_commit_fields/migration.sql +38 -0
  295. package/prisma/schema.prisma +64 -0
  296. package/dist/web/assets/CreateTaskInput-Cb3aRHr3.js +0 -1
  297. package/dist/web/assets/GeneralSettingsPage-CE7P3t_v.js +0 -1
  298. package/dist/web/assets/McpSettingsPage-gp1XDMUd.js +0 -1
  299. package/dist/web/assets/NotificationSettingsPage-BhZeHEef.js +0 -1
  300. package/dist/web/assets/ProfileSettingsPage-D_y3ePFs.js +0 -3
  301. package/dist/web/assets/ProjectSettingsPage-V38j8T61.js +0 -2
  302. package/dist/web/assets/channel-CWEYGfCJ.js +0 -1
  303. package/dist/web/assets/check-D2WWIhwV.js +0 -1
  304. package/dist/web/assets/classDiagram-4FO5ZUOK-CcU8zfK8.js +0 -1
  305. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-CcU8zfK8.js +0 -1
  306. package/dist/web/assets/confirm-dialog-BAqfLDT8.js +0 -1
  307. package/dist/web/assets/folder-picker-DFB9_pv4.js +0 -1
  308. package/dist/web/assets/folder-u7fKAtz_.js +0 -1
  309. package/dist/web/assets/index-7nw4fV42.js +0 -122
  310. package/dist/web/assets/index-YCjjSSLC.css +0 -1
  311. package/dist/web/assets/input-CKwRYuUJ.js +0 -1
  312. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-CudtEyHd.js +0 -1
@@ -7,12 +7,24 @@ import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vites
7
7
  const testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-tower-team-run-'));
8
8
  const dbPath = path.join(testDir, 'test.db');
9
9
  process.env.AGENT_TOWER_DATABASE_URL = `file:${dbPath}`;
10
- const { appendAttachmentMarkdownContextMock } = vi.hoisted(() => ({
10
+ const { appendAttachmentMarkdownContextMock, fakeEventBus } = vi.hoisted(() => ({
11
11
  appendAttachmentMarkdownContextMock: vi.fn(),
12
+ fakeEventBus: {
13
+ emit: vi.fn(),
14
+ on: vi.fn(),
15
+ off: vi.fn(),
16
+ },
12
17
  }));
13
18
  vi.mock('../attachment-context.js', () => ({
14
19
  appendAttachmentMarkdownContext: appendAttachmentMarkdownContextMock,
15
20
  }));
21
+ vi.mock('../../core/container.js', async (importOriginal) => {
22
+ const actual = await importOriginal();
23
+ return {
24
+ ...actual,
25
+ getEventBus: vi.fn(() => fakeEventBus),
26
+ };
27
+ });
16
28
  const __filename = fileURLToPath(import.meta.url);
17
29
  const __dirname = path.dirname(__filename);
18
30
  const serverRoot = path.resolve(__dirname, '../../..');
@@ -54,7 +66,13 @@ function userMessagesPresetInput(name, aliases = [name.toLowerCase()]) {
54
66
  }
55
67
  function createGitRepoPath(label) {
56
68
  const repoPath = path.join(testDir, 'repos', `${label}-${gitRepoCounter++}`);
57
- fs.mkdirSync(path.join(repoPath, '.git'), { recursive: true });
69
+ fs.mkdirSync(repoPath, { recursive: true });
70
+ execFileSync('git', ['init'], { cwd: repoPath, stdio: 'pipe' });
71
+ execFileSync('git', ['config', 'user.email', 'test@example.com'], { cwd: repoPath, stdio: 'pipe' });
72
+ execFileSync('git', ['config', 'user.name', 'Test User'], { cwd: repoPath, stdio: 'pipe' });
73
+ fs.writeFileSync(path.join(repoPath, 'README.md'), 'initial\n', 'utf-8');
74
+ execFileSync('git', ['add', 'README.md'], { cwd: repoPath, stdio: 'pipe' });
75
+ execFileSync('git', ['commit', '-m', 'initial commit'], { cwd: repoPath, stdio: 'pipe' });
58
76
  return repoPath;
59
77
  }
60
78
  async function createTask(title = 'Team task') {
@@ -85,6 +103,9 @@ describe('TeamRunService', () => {
85
103
  prisma = utilsModule.prisma;
86
104
  });
87
105
  beforeEach(async () => {
106
+ fakeEventBus.emit.mockClear();
107
+ fakeEventBus.on.mockClear();
108
+ fakeEventBus.off.mockClear();
88
109
  appendAttachmentMarkdownContextMock.mockImplementation(async (content, attachmentIds) => {
89
110
  const ids = Array.from(new Set((attachmentIds ?? []).map((id) => id.trim()).filter(Boolean)));
90
111
  if (ids.length === 0)
@@ -323,11 +344,43 @@ describe('TeamRunService', () => {
323
344
  expect(listed).toBeDefined();
324
345
  expect(listed?.content).not.toBe(fullContent);
325
346
  expect(listed?.contentPreview).toBe(listed?.content);
347
+ expect(listed?.contentMode).toBe('preview');
348
+ expect(listed?.fullContentAvailable).toBe(true);
326
349
  expect(listed?.isTruncated).toBe(true);
327
350
  expect(detail.content).toBe(fullContent);
328
351
  expect(detail.contentPreview).toBe(listed?.contentPreview);
352
+ expect(detail.contentMode).toBe('full');
353
+ expect(detail.fullContentAvailable).toBe(false);
329
354
  expect(detail.isTruncated).toBe(true);
330
355
  });
356
+ it('limits RoomMessage lists at the service query boundary while preserving chronological order', async () => {
357
+ const preset = await service.createMemberPreset(presetInput('Coder'));
358
+ const task = await createTask();
359
+ const teamRun = await service.createTeamRun(task.id, {
360
+ mode: 'AUTO',
361
+ memberPresetIds: [preset.id],
362
+ });
363
+ const first = await service.createRoomMessage(teamRun.id, { content: 'First note' });
364
+ const second = await service.createRoomMessage(teamRun.id, { content: 'Second note' });
365
+ const third = await service.createRoomMessage(teamRun.id, { content: 'Third note' });
366
+ await prisma.roomMessage.update({
367
+ where: { id: first.id },
368
+ data: { createdAt: new Date('2026-01-01T00:00:00.000Z') },
369
+ });
370
+ await prisma.roomMessage.update({
371
+ where: { id: second.id },
372
+ data: { createdAt: new Date('2026-01-01T00:00:01.000Z') },
373
+ });
374
+ await prisma.roomMessage.update({
375
+ where: { id: third.id },
376
+ data: { createdAt: new Date('2026-01-01T00:00:02.000Z') },
377
+ });
378
+ const messages = await service.listRoomMessages(teamRun.id, { limit: 2 });
379
+ expect(messages.map((message) => message.id)).toEqual([second.id, third.id]);
380
+ expect(messages.map((message) => message.content)).toEqual(['Second note', 'Third note']);
381
+ expect(messages.map((message) => message.contentMode)).toEqual(['full', 'full']);
382
+ expect(messages.find((message) => message.id === first.id)).toBeUndefined();
383
+ });
331
384
  it('creates WorkRequests for USER_MESSAGES members when a user message has no mentions', async () => {
332
385
  const leaderPreset = await service.createMemberPreset(userMessagesPresetInput('Leader'));
333
386
  const coderPreset = await service.createMemberPreset(presetInput('Coder'));
@@ -390,8 +443,12 @@ describe('TeamRunService', () => {
390
443
  const listed = await service.listRoomMessages(teamRun.id);
391
444
  const detail = await service.getRoomMessage(teamRun.id, teamRun.messages[0].id);
392
445
  expect(listed[0]?.isTruncated).toBe(true);
446
+ expect(listed[0]?.contentMode).toBe('preview');
447
+ expect(listed[0]?.fullContentAvailable).toBe(true);
393
448
  expect(listed[0]?.content).not.toContain('line '.repeat(100));
394
449
  expect(detail.content).toBe(storedMessage.content);
450
+ expect(detail.contentMode).toBe('full');
451
+ expect(detail.fullContentAvailable).toBe(false);
395
452
  expect(detail.content).toContain('line '.repeat(100));
396
453
  });
397
454
  it('parses initial TeamRun mentions from the full task body and stores the full description', async () => {
@@ -487,6 +544,266 @@ describe('TeamRunService', () => {
487
544
  status: 'PENDING_APPROVAL',
488
545
  });
489
546
  });
547
+ it('persists target commit metadata from RoomMessage mentions', async () => {
548
+ const reviewerPreset = await service.createMemberPreset(presetInput('Reviewer'));
549
+ const task = await createTask();
550
+ const teamRun = await service.createTeamRun(task.id, {
551
+ mode: 'CONFIRM',
552
+ memberPresetIds: [reviewerPreset.id],
553
+ });
554
+ const member = teamRun.members?.[0];
555
+ expect(member).toBeDefined();
556
+ const sourceWorkspace = await prisma.workspace.create({
557
+ data: {
558
+ taskId: task.id,
559
+ parentWorkspaceId: null,
560
+ ownerMemberId: null,
561
+ branchName: 'source-branch',
562
+ worktreePath: path.join(testDir, 'source-workspace'),
563
+ status: 'ACTIVE',
564
+ },
565
+ });
566
+ const message = await service.createRoomMessage(teamRun.id, {
567
+ content: 'Please review this commit',
568
+ mentions: [{
569
+ memberId: member.id,
570
+ target: {
571
+ kind: 'WORKSPACE_COMMIT',
572
+ purpose: 'REVIEW',
573
+ sourceWorkspaceId: sourceWorkspace.id,
574
+ headSha: 'a'.repeat(40),
575
+ branchName: sourceWorkspace.branchName,
576
+ planItemId: 'plan-1',
577
+ },
578
+ }],
579
+ });
580
+ const requests = await service.listWorkRequests(teamRun.id);
581
+ expect(message.mentions[0]?.target).toMatchObject({
582
+ kind: 'WORKSPACE_COMMIT',
583
+ purpose: 'REVIEW',
584
+ sourceWorkspaceId: sourceWorkspace.id,
585
+ headSha: 'a'.repeat(40),
586
+ });
587
+ expect(requests).toHaveLength(1);
588
+ expect(requests[0]).toMatchObject({
589
+ targetKind: 'WORKSPACE_COMMIT',
590
+ targetPurpose: 'REVIEW',
591
+ targetSourceWorkspaceId: sourceWorkspace.id,
592
+ targetSourceMemberId: null,
593
+ targetHeadSha: 'a'.repeat(40),
594
+ targetBranchName: sourceWorkspace.branchName,
595
+ targetPlanItemId: 'plan-1',
596
+ });
597
+ });
598
+ it('rejects target commit metadata for source workspaces outside the TeamRun', async () => {
599
+ const reviewerPreset = await service.createMemberPreset(presetInput('Reviewer'));
600
+ const task = await createTask();
601
+ const otherTask = await createTask('Other task');
602
+ const teamRun = await service.createTeamRun(task.id, {
603
+ mode: 'AUTO',
604
+ memberPresetIds: [reviewerPreset.id],
605
+ });
606
+ const member = teamRun.members?.[0];
607
+ expect(member).toBeDefined();
608
+ const otherWorkspace = await prisma.workspace.create({
609
+ data: {
610
+ taskId: otherTask.id,
611
+ branchName: 'other-source',
612
+ worktreePath: path.join(testDir, 'other-source'),
613
+ status: 'ACTIVE',
614
+ },
615
+ });
616
+ await expect(service.createRoomMessage(teamRun.id, {
617
+ content: 'Please review this commit',
618
+ mentions: [{
619
+ memberId: member.id,
620
+ target: {
621
+ kind: 'WORKSPACE_COMMIT',
622
+ purpose: 'REVIEW',
623
+ sourceWorkspaceId: otherWorkspace.id,
624
+ headSha: 'b'.repeat(40),
625
+ branchName: otherWorkspace.branchName,
626
+ },
627
+ }],
628
+ })).rejects.toMatchObject({
629
+ code: 'VALIDATION_ERROR',
630
+ statusCode: 400,
631
+ });
632
+ await expect(prisma.workRequest.count({ where: { teamRunId: teamRun.id } })).resolves.toBe(0);
633
+ });
634
+ it('immediately completes a waiting invocation when its agent posts a RoomMessage and starts queued work', async () => {
635
+ const preset = await service.createMemberPreset({
636
+ ...presetInput('Coder'),
637
+ workspacePolicy: 'shared',
638
+ });
639
+ const task = await createTask();
640
+ const workspace = await prisma.workspace.create({
641
+ data: {
642
+ taskId: task.id,
643
+ branchName: '',
644
+ worktreePath: '',
645
+ workspaceKind: 'MAIN_DIRECTORY',
646
+ workingDir: testDir,
647
+ status: 'ACTIVE',
648
+ },
649
+ });
650
+ const teamRun = await service.createTeamRun(task.id, {
651
+ mode: 'AUTO',
652
+ memberPresetIds: [preset.id],
653
+ });
654
+ await prisma.teamRun.update({
655
+ where: { id: teamRun.id },
656
+ data: { mainWorkspaceId: workspace.id },
657
+ });
658
+ const member = teamRun.members[0];
659
+ const firstRequest = await prisma.workRequest.create({
660
+ data: {
661
+ teamRunId: teamRun.id,
662
+ requesterType: 'user',
663
+ targetMemberId: member.id,
664
+ triggerMessageId: 'message-waiting',
665
+ instruction: 'Finish current work',
666
+ status: 'STARTED',
667
+ },
668
+ });
669
+ const queuedRequest = await prisma.workRequest.create({
670
+ data: {
671
+ teamRunId: teamRun.id,
672
+ requesterType: 'user',
673
+ targetMemberId: member.id,
674
+ triggerMessageId: 'message-queued',
675
+ instruction: 'Start next work',
676
+ status: 'QUEUED',
677
+ },
678
+ });
679
+ const session = await prisma.session.create({
680
+ data: {
681
+ workspaceId: workspace.id,
682
+ agentType: 'CODEX',
683
+ providerId: member.providerId,
684
+ prompt: 'current work',
685
+ status: 'COMPLETED',
686
+ },
687
+ });
688
+ const invocation = await prisma.agentInvocation.create({
689
+ data: {
690
+ teamRunId: teamRun.id,
691
+ workRequestId: firstRequest.id,
692
+ memberId: member.id,
693
+ workspaceId: workspace.id,
694
+ sessionId: session.id,
695
+ status: 'WAITING_ROOM_REPLY',
696
+ roomReplyReminderCount: 4,
697
+ nextRoomReplyReminderAt: new Date(Date.UTC(2026, 0, 1, 0, 5, 0)),
698
+ firstNudgeAt: new Date(Date.UTC(2026, 0, 1, 0, 0, 0)),
699
+ },
700
+ });
701
+ const { TeamReconcilerService } = await import('../team-reconciler.service.js');
702
+ const scheduler = {
703
+ releaseInvocationLocks: vi.fn(),
704
+ startNextSessions: vi.fn(async () => []),
705
+ };
706
+ service.reconciler = new TeamReconcilerService({
707
+ scheduler,
708
+ eventBus: fakeEventBus,
709
+ scheduleReminders: false,
710
+ });
711
+ const message = await service.createRoomMessage(teamRun.id, {
712
+ content: 'Result posted',
713
+ senderType: 'agent',
714
+ senderId: member.id,
715
+ senderInvocationId: invocation.id,
716
+ });
717
+ expect(message.senderInvocationId).toBe(invocation.id);
718
+ await expect(prisma.agentInvocation.findUnique({ where: { id: invocation.id } })).resolves.toMatchObject({
719
+ status: 'COMPLETED',
720
+ roomReplyReminderCount: 0,
721
+ nextRoomReplyReminderAt: null,
722
+ firstNudgeAt: null,
723
+ });
724
+ await expect(prisma.workRequest.findUnique({ where: { id: firstRequest.id } })).resolves.toMatchObject({
725
+ status: 'COMPLETED',
726
+ });
727
+ await expect(prisma.workRequest.findUnique({ where: { id: queuedRequest.id } })).resolves.toMatchObject({
728
+ status: 'QUEUED',
729
+ });
730
+ expect(scheduler.releaseInvocationLocks).toHaveBeenCalledWith(invocation.id);
731
+ expect(scheduler.startNextSessions).toHaveBeenCalledWith(teamRun.id);
732
+ });
733
+ it('does not complete a waiting invocation for user or system RoomMessages', async () => {
734
+ const preset = await service.createMemberPreset(presetInput('Coder'));
735
+ const task = await createTask();
736
+ const workspace = await prisma.workspace.create({
737
+ data: {
738
+ taskId: task.id,
739
+ branchName: 'team-shared',
740
+ worktreePath: testDir,
741
+ status: 'ACTIVE',
742
+ },
743
+ });
744
+ const teamRun = await service.createTeamRun(task.id, {
745
+ mode: 'AUTO',
746
+ memberPresetIds: [preset.id],
747
+ });
748
+ const member = teamRun.members[0];
749
+ const request = await prisma.workRequest.create({
750
+ data: {
751
+ teamRunId: teamRun.id,
752
+ requesterType: 'user',
753
+ targetMemberId: member.id,
754
+ triggerMessageId: 'message-waiting-user',
755
+ instruction: 'Finish current work',
756
+ status: 'STARTED',
757
+ },
758
+ });
759
+ const session = await prisma.session.create({
760
+ data: {
761
+ workspaceId: workspace.id,
762
+ agentType: 'CODEX',
763
+ providerId: member.providerId,
764
+ prompt: 'current work',
765
+ status: 'COMPLETED',
766
+ },
767
+ });
768
+ const invocation = await prisma.agentInvocation.create({
769
+ data: {
770
+ teamRunId: teamRun.id,
771
+ workRequestId: request.id,
772
+ memberId: member.id,
773
+ workspaceId: workspace.id,
774
+ sessionId: session.id,
775
+ status: 'WAITING_ROOM_REPLY',
776
+ roomReplyReminderCount: 4,
777
+ nextRoomReplyReminderAt: new Date(Date.UTC(2026, 0, 1, 0, 5, 0)),
778
+ },
779
+ });
780
+ const userMessage = await service.createRoomMessage(teamRun.id, {
781
+ content: 'Host note',
782
+ senderType: 'user',
783
+ senderInvocationId: invocation.id,
784
+ });
785
+ const systemMessage = await service.createRoomMessage(teamRun.id, {
786
+ content: 'System note',
787
+ senderType: 'system',
788
+ senderInvocationId: invocation.id,
789
+ });
790
+ expect(userMessage.senderInvocationId).toBeNull();
791
+ expect(systemMessage.senderInvocationId).toBeNull();
792
+ await expect(prisma.roomMessage.findMany({
793
+ where: { id: { in: [userMessage.id, systemMessage.id] } },
794
+ orderBy: { createdAt: 'asc' },
795
+ })).resolves.toEqual([
796
+ expect.objectContaining({ senderType: 'user', senderInvocationId: null }),
797
+ expect.objectContaining({ senderType: 'system', senderInvocationId: null }),
798
+ ]);
799
+ await expect(prisma.agentInvocation.findUnique({ where: { id: invocation.id } })).resolves.toMatchObject({
800
+ status: 'WAITING_ROOM_REPLY',
801
+ roomReplyReminderCount: 4,
802
+ });
803
+ await expect(prisma.workRequest.findUnique({ where: { id: request.id } })).resolves.toMatchObject({
804
+ status: 'STARTED',
805
+ });
806
+ });
490
807
  it('creates private RoomMessages with participants and WorkRequests for recipients', async () => {
491
808
  const senderPreset = await service.createMemberPreset(presetInput('Sender'));
492
809
  const recipientPreset = await service.createMemberPreset(presetInput('Recipient'));
@@ -536,6 +853,55 @@ describe('TeamRunService', () => {
536
853
  await expect(service.listRoomMessages(teamRun.id, { viewerMemberId: recipient.id })).resolves.toEqual(expect.arrayContaining([expect.objectContaining({ id: message.id })]));
537
854
  await expect(service.listRoomMessages(teamRun.id, { viewerMemberId: observer.id })).resolves.toEqual([]);
538
855
  });
856
+ it('persists target commit metadata from private RoomMessages', async () => {
857
+ const senderPreset = await service.createMemberPreset(presetInput('Sender'));
858
+ const recipientPreset = await service.createMemberPreset(presetInput('Recipient'));
859
+ const task = await createTask();
860
+ const teamRun = await service.createTeamRun(task.id, {
861
+ mode: 'AUTO',
862
+ memberPresetIds: [senderPreset.id, recipientPreset.id],
863
+ });
864
+ const sender = teamRun.members?.find((member) => member.name === 'Sender');
865
+ const recipient = teamRun.members?.find((member) => member.name === 'Recipient');
866
+ expect(sender).toBeDefined();
867
+ expect(recipient).toBeDefined();
868
+ const sourceWorkspace = await prisma.workspace.create({
869
+ data: {
870
+ taskId: task.id,
871
+ parentWorkspaceId: null,
872
+ ownerMemberId: sender.id,
873
+ branchName: 'private-source',
874
+ worktreePath: path.join(testDir, 'private-source-workspace'),
875
+ status: 'ACTIVE',
876
+ },
877
+ });
878
+ await service.createPrivateRoomMessage(teamRun.id, {
879
+ content: 'Private targeted test',
880
+ recipientMemberIds: [recipient.id],
881
+ target: {
882
+ kind: 'WORKSPACE_COMMIT',
883
+ purpose: 'TEST',
884
+ sourceWorkspaceId: sourceWorkspace.id,
885
+ headSha: 'c'.repeat(40),
886
+ branchName: sourceWorkspace.branchName,
887
+ planItemId: 'private-plan',
888
+ },
889
+ senderType: 'agent',
890
+ senderId: sender.id,
891
+ });
892
+ const requests = await service.listWorkRequests(teamRun.id);
893
+ expect(requests).toHaveLength(1);
894
+ expect(requests[0]).toMatchObject({
895
+ targetMemberId: recipient.id,
896
+ targetKind: 'WORKSPACE_COMMIT',
897
+ targetPurpose: 'TEST',
898
+ targetSourceWorkspaceId: sourceWorkspace.id,
899
+ targetSourceMemberId: sender.id,
900
+ targetHeadSha: 'c'.repeat(40),
901
+ targetBranchName: sourceWorkspace.branchName,
902
+ targetPlanItemId: 'private-plan',
903
+ });
904
+ });
539
905
  it('records user private message senderId as a sender participant when provided', async () => {
540
906
  const senderPreset = await service.createMemberPreset(presetInput('HostSender'));
541
907
  const recipientPreset = await service.createMemberPreset(presetInput('Recipient'));