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
@@ -41,6 +41,20 @@ const commandCapabilities = {
41
41
  function stringifyJson(value) {
42
42
  return JSON.stringify(value);
43
43
  }
44
+ function git(cwd, args) {
45
+ return execFileSync('git', args, { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
46
+ }
47
+ function initGitRepo(repoPath) {
48
+ fs.mkdirSync(repoPath, { recursive: true });
49
+ git(repoPath, ['init']);
50
+ git(repoPath, ['checkout', '-B', 'main']);
51
+ git(repoPath, ['config', 'user.email', 'test@example.com']);
52
+ git(repoPath, ['config', 'user.name', 'Test User']);
53
+ fs.writeFileSync(path.join(repoPath, 'README.md'), '# test\n');
54
+ git(repoPath, ['add', 'README.md']);
55
+ git(repoPath, ['commit', '-m', 'initial commit']);
56
+ return git(repoPath, ['rev-parse', 'HEAD']).trim();
57
+ }
44
58
  async function createTask(title = 'Team scheduler task', status = TaskStatus.TODO) {
45
59
  const project = await prisma.project.create({
46
60
  data: {
@@ -103,6 +117,7 @@ async function createWorkRequest(options) {
103
117
  requesterMemberId: null,
104
118
  requesterType: 'user',
105
119
  targetMemberId: options.targetMemberId,
120
+ ...(options.target ?? {}),
106
121
  triggerMessageId: options.triggerMessageId ?? `message-${Math.random().toString(16).slice(2)}`,
107
122
  instruction: options.instruction ?? 'Please do the work',
108
123
  ifBusy: options.ifBusy ?? 'queue',
@@ -1001,6 +1016,308 @@ describe('TeamSchedulerService', () => {
1001
1016
  members[1].id,
1002
1017
  ]));
1003
1018
  });
1019
+ it('marks targeted review/test requests for non-dedicated members as failed', async () => {
1020
+ const { workspace: sourceWorkspace, teamRun, members } = await createTeamRunFixture({
1021
+ memberCapabilities: [commandCapabilities],
1022
+ workspacePolicies: ['shared'],
1023
+ });
1024
+ const request = await createWorkRequest({
1025
+ teamRunId: teamRun.id,
1026
+ targetMemberId: members[0].id,
1027
+ target: {
1028
+ targetKind: 'WORKSPACE_COMMIT',
1029
+ targetPurpose: 'REVIEW',
1030
+ targetSourceWorkspaceId: sourceWorkspace.id,
1031
+ targetHeadSha: 'a'.repeat(40),
1032
+ targetBranchName: sourceWorkspace.branchName,
1033
+ },
1034
+ });
1035
+ const sessionManager = createSessionManagerMock();
1036
+ service = new TeamSchedulerService(lockService, {
1037
+ workspaceService: createWorkspaceServiceMock(),
1038
+ sessionManager,
1039
+ getProviderById: createProviderLookup(),
1040
+ });
1041
+ await expect(service.planNext(teamRun.id)).resolves.toEqual([
1042
+ expect.objectContaining({
1043
+ workRequestId: request.id,
1044
+ canStart: false,
1045
+ blockedReason: 'unsupported_workspace_policy',
1046
+ }),
1047
+ ]);
1048
+ const invocations = await service.startNextSessions(teamRun.id);
1049
+ expect(invocations).toEqual([]);
1050
+ expect(sessionManager.create).not.toHaveBeenCalled();
1051
+ const invocation = await prisma.agentInvocation.findFirst({ where: { workRequestId: request.id } });
1052
+ expect(invocation).toMatchObject({
1053
+ status: 'FAILED',
1054
+ targetSyncError: expect.stringContaining('workspacePolicy=dedicated'),
1055
+ targetKind: 'WORKSPACE_COMMIT',
1056
+ targetPurpose: 'REVIEW',
1057
+ });
1058
+ expect(invocation?.targetSyncError).toContain('workspacePolicy=shared');
1059
+ await expect(prisma.roomMessage.findFirst({ where: { senderInvocationId: invocation?.id ?? '' } })).resolves.toMatchObject({
1060
+ senderType: 'system',
1061
+ kind: 'system',
1062
+ content: expect.stringContaining('change this TeamMember instance to workspacePolicy=dedicated'),
1063
+ workRequestIds: JSON.stringify([request.id]),
1064
+ });
1065
+ await expect(prisma.workRequest.findUnique({ where: { id: request.id } })).resolves.toMatchObject({
1066
+ status: 'STARTED',
1067
+ });
1068
+ });
1069
+ it('syncs a targeted dedicated execution workspace to the target commit before starting', async () => {
1070
+ const repoPath = path.join(testDir, 'target-sync-success-repo');
1071
+ const targetSha = initGitRepo(repoPath);
1072
+ const { project, task } = await createTask('Target sync success task');
1073
+ await prisma.project.update({ where: { id: project.id }, data: { repoPath } });
1074
+ const teamRun = await prisma.teamRun.create({ data: { taskId: task.id, mode: 'AUTO' } });
1075
+ const mainWorkspace = await prisma.workspace.create({
1076
+ data: {
1077
+ taskId: task.id,
1078
+ branchName: 'main',
1079
+ baseBranch: 'main',
1080
+ worktreePath: repoPath,
1081
+ workingDir: repoPath,
1082
+ status: 'ACTIVE',
1083
+ },
1084
+ });
1085
+ await prisma.teamRun.update({ where: { id: teamRun.id }, data: { mainWorkspaceId: mainWorkspace.id } });
1086
+ const sourceWorkspace = await prisma.workspace.create({
1087
+ data: {
1088
+ taskId: task.id,
1089
+ parentWorkspaceId: mainWorkspace.id,
1090
+ ownerMemberId: null,
1091
+ branchName: 'source-delivery',
1092
+ baseBranch: 'main',
1093
+ worktreePath: repoPath,
1094
+ workingDir: repoPath,
1095
+ status: 'ACTIVE',
1096
+ },
1097
+ });
1098
+ const member = await prisma.teamMember.create({
1099
+ data: {
1100
+ teamRunId: teamRun.id,
1101
+ presetId: null,
1102
+ name: 'Tester',
1103
+ aliases: stringifyJson(['tester']),
1104
+ providerId: 'provider-1',
1105
+ rolePrompt: 'Test role',
1106
+ capabilities: stringifyJson(commandCapabilities),
1107
+ workspacePolicy: 'dedicated',
1108
+ triggerPolicy: 'MENTION_ONLY',
1109
+ sessionPolicy: 'new_per_request',
1110
+ queueManagementPolicy: 'own_only',
1111
+ avatar: null,
1112
+ },
1113
+ });
1114
+ const request = await createWorkRequest({
1115
+ teamRunId: teamRun.id,
1116
+ targetMemberId: member.id,
1117
+ target: {
1118
+ targetKind: 'WORKSPACE_COMMIT',
1119
+ targetPurpose: 'TEST',
1120
+ targetSourceWorkspaceId: sourceWorkspace.id,
1121
+ targetHeadSha: targetSha,
1122
+ targetBranchName: sourceWorkspace.branchName,
1123
+ targetPlanItemId: 'plan-sync',
1124
+ },
1125
+ });
1126
+ const sessionManager = createSessionManagerMock();
1127
+ service = new TeamSchedulerService(lockService, {
1128
+ sessionManager,
1129
+ getProviderById: createProviderLookup(),
1130
+ });
1131
+ const invocations = await service.startNextSessions(teamRun.id);
1132
+ expect(invocations).toHaveLength(1);
1133
+ const invocation = await prisma.agentInvocation.findUniqueOrThrow({ where: { id: invocations[0].id } });
1134
+ expect(invocation).toMatchObject({
1135
+ workRequestId: request.id,
1136
+ targetKind: 'WORKSPACE_COMMIT',
1137
+ targetPurpose: 'TEST',
1138
+ targetSourceWorkspaceId: sourceWorkspace.id,
1139
+ targetHeadSha: targetSha,
1140
+ targetSyncStatus: 'SYNCED',
1141
+ targetSyncError: null,
1142
+ targetPlanItemId: 'plan-sync',
1143
+ targetPort: expect.any(Number),
1144
+ targetVitePort: expect.any(Number),
1145
+ targetE2EPort: expect.any(Number),
1146
+ });
1147
+ expect(invocation.targetExecutionBranch).toBe(`at/team/${teamRun.id.slice(0, 8)}/target/test-${member.id.slice(0, 8)}-${targetSha.slice(0, 12)}`);
1148
+ const executionWorkspace = await prisma.workspace.findUniqueOrThrow({ where: { id: invocation.workspaceId } });
1149
+ expect(executionWorkspace.branchName).toBe(invocation.targetExecutionBranch);
1150
+ expect(git(executionWorkspace.worktreePath, ['rev-parse', 'HEAD']).trim()).toBe(targetSha);
1151
+ expect(sessionManager.create).toHaveBeenCalledWith(executionWorkspace.id, AgentType.CODEX, buildExpectedSessionPrompt('Test role', [
1152
+ 'Target sync success task',
1153
+ [
1154
+ 'Target commit handoff:',
1155
+ '- purpose: TEST',
1156
+ `- sourceWorkspaceId: ${sourceWorkspace.id}`,
1157
+ `- targetHeadSha: ${targetSha}`,
1158
+ `- sourceBranch: ${sourceWorkspace.branchName}`,
1159
+ '- planItemId: plan-sync',
1160
+ '- The execution workspace is synced to targetHeadSha before this session starts.',
1161
+ '- Record review/test verdicts against sourceWorkspaceId with reviewed_sha=targetHeadSha.',
1162
+ ].join('\n'),
1163
+ 'Work request summary:\nPlease do the work',
1164
+ ].join('\n\n')), 'DEFAULT', member.providerId);
1165
+ }, 15_000);
1166
+ it('fails targeted sync when the execution workspace is dirty', async () => {
1167
+ const repoPath = path.join(testDir, 'target-sync-dirty-repo');
1168
+ const targetSha = initGitRepo(repoPath);
1169
+ const { project, task } = await createTask('Target sync dirty task');
1170
+ await prisma.project.update({ where: { id: project.id }, data: { repoPath } });
1171
+ const teamRun = await prisma.teamRun.create({ data: { taskId: task.id, mode: 'AUTO' } });
1172
+ const mainWorkspace = await prisma.workspace.create({
1173
+ data: {
1174
+ taskId: task.id,
1175
+ branchName: 'main',
1176
+ baseBranch: 'main',
1177
+ worktreePath: repoPath,
1178
+ workingDir: repoPath,
1179
+ status: 'ACTIVE',
1180
+ },
1181
+ });
1182
+ await prisma.teamRun.update({ where: { id: teamRun.id }, data: { mainWorkspaceId: mainWorkspace.id } });
1183
+ const sourceWorkspace = await prisma.workspace.create({
1184
+ data: {
1185
+ taskId: task.id,
1186
+ parentWorkspaceId: mainWorkspace.id,
1187
+ ownerMemberId: null,
1188
+ branchName: 'source-delivery-dirty',
1189
+ baseBranch: 'main',
1190
+ worktreePath: repoPath,
1191
+ workingDir: repoPath,
1192
+ status: 'ACTIVE',
1193
+ },
1194
+ });
1195
+ const member = await prisma.teamMember.create({
1196
+ data: {
1197
+ teamRunId: teamRun.id,
1198
+ presetId: null,
1199
+ name: 'Reviewer',
1200
+ aliases: stringifyJson(['reviewer']),
1201
+ providerId: 'provider-1',
1202
+ rolePrompt: 'Review role',
1203
+ capabilities: stringifyJson(commandCapabilities),
1204
+ workspacePolicy: 'dedicated',
1205
+ triggerPolicy: 'MENTION_ONLY',
1206
+ sessionPolicy: 'new_per_request',
1207
+ queueManagementPolicy: 'own_only',
1208
+ avatar: null,
1209
+ },
1210
+ });
1211
+ const executionWorkspace = await prisma.workspace.create({
1212
+ data: {
1213
+ taskId: task.id,
1214
+ parentWorkspaceId: mainWorkspace.id,
1215
+ ownerMemberId: member.id,
1216
+ branchName: `at/team/${teamRun.id.slice(0, 8)}/member-${member.id.slice(0, 8)}`,
1217
+ baseBranch: mainWorkspace.branchName,
1218
+ worktreePath: await import('../../git/worktree.manager.js').then(async ({ WorktreeManager }) => {
1219
+ const manager = new WorktreeManager(repoPath);
1220
+ return manager.create(`at/team/${teamRun.id.slice(0, 8)}/member-${member.id.slice(0, 8)}`);
1221
+ }),
1222
+ status: 'ACTIVE',
1223
+ },
1224
+ });
1225
+ fs.writeFileSync(path.join(executionWorkspace.worktreePath, 'dirty.txt'), 'dirty');
1226
+ const request = await createWorkRequest({
1227
+ teamRunId: teamRun.id,
1228
+ targetMemberId: member.id,
1229
+ target: {
1230
+ targetKind: 'WORKSPACE_COMMIT',
1231
+ targetPurpose: 'REVIEW',
1232
+ targetSourceWorkspaceId: sourceWorkspace.id,
1233
+ targetHeadSha: targetSha,
1234
+ targetBranchName: sourceWorkspace.branchName,
1235
+ },
1236
+ });
1237
+ const sessionManager = createSessionManagerMock();
1238
+ service = new TeamSchedulerService(lockService, {
1239
+ sessionManager,
1240
+ getProviderById: createProviderLookup(),
1241
+ });
1242
+ const invocations = await service.startNextSessions(teamRun.id);
1243
+ expect(invocations).toEqual([]);
1244
+ expect(sessionManager.create).not.toHaveBeenCalled();
1245
+ await expect(prisma.agentInvocation.findFirst({ where: { workRequestId: request.id } })).resolves.toMatchObject({
1246
+ workspaceId: executionWorkspace.id,
1247
+ status: 'FAILED',
1248
+ targetSyncStatus: 'FAILED',
1249
+ targetSyncError: expect.stringContaining('Execution workspace has uncommitted changes'),
1250
+ });
1251
+ }, 15_000);
1252
+ it('fails targeted sync when the target commit does not exist', async () => {
1253
+ const repoPath = path.join(testDir, 'target-sync-missing-sha-repo');
1254
+ initGitRepo(repoPath);
1255
+ const { project, task } = await createTask('Target sync missing sha task');
1256
+ await prisma.project.update({ where: { id: project.id }, data: { repoPath } });
1257
+ const teamRun = await prisma.teamRun.create({ data: { taskId: task.id, mode: 'AUTO' } });
1258
+ const mainWorkspace = await prisma.workspace.create({
1259
+ data: {
1260
+ taskId: task.id,
1261
+ branchName: 'main',
1262
+ baseBranch: 'main',
1263
+ worktreePath: repoPath,
1264
+ workingDir: repoPath,
1265
+ status: 'ACTIVE',
1266
+ },
1267
+ });
1268
+ await prisma.teamRun.update({ where: { id: teamRun.id }, data: { mainWorkspaceId: mainWorkspace.id } });
1269
+ const sourceWorkspace = await prisma.workspace.create({
1270
+ data: {
1271
+ taskId: task.id,
1272
+ parentWorkspaceId: mainWorkspace.id,
1273
+ ownerMemberId: null,
1274
+ branchName: 'source-delivery-missing',
1275
+ baseBranch: 'main',
1276
+ worktreePath: repoPath,
1277
+ workingDir: repoPath,
1278
+ status: 'ACTIVE',
1279
+ },
1280
+ });
1281
+ const member = await prisma.teamMember.create({
1282
+ data: {
1283
+ teamRunId: teamRun.id,
1284
+ presetId: null,
1285
+ name: 'Reviewer',
1286
+ aliases: stringifyJson(['reviewer']),
1287
+ providerId: 'provider-1',
1288
+ rolePrompt: 'Review role',
1289
+ capabilities: stringifyJson(commandCapabilities),
1290
+ workspacePolicy: 'dedicated',
1291
+ triggerPolicy: 'MENTION_ONLY',
1292
+ sessionPolicy: 'new_per_request',
1293
+ queueManagementPolicy: 'own_only',
1294
+ avatar: null,
1295
+ },
1296
+ });
1297
+ const request = await createWorkRequest({
1298
+ teamRunId: teamRun.id,
1299
+ targetMemberId: member.id,
1300
+ target: {
1301
+ targetKind: 'WORKSPACE_COMMIT',
1302
+ targetPurpose: 'REVIEW',
1303
+ targetSourceWorkspaceId: sourceWorkspace.id,
1304
+ targetHeadSha: 'f'.repeat(40),
1305
+ targetBranchName: sourceWorkspace.branchName,
1306
+ },
1307
+ });
1308
+ const sessionManager = createSessionManagerMock();
1309
+ service = new TeamSchedulerService(lockService, {
1310
+ sessionManager,
1311
+ getProviderById: createProviderLookup(),
1312
+ });
1313
+ await expect(service.startNextSessions(teamRun.id)).resolves.toEqual([]);
1314
+ expect(sessionManager.create).not.toHaveBeenCalled();
1315
+ await expect(prisma.agentInvocation.findFirst({ where: { workRequestId: request.id } })).resolves.toMatchObject({
1316
+ status: 'FAILED',
1317
+ targetSyncStatus: 'FAILED',
1318
+ targetSyncError: expect.stringContaining('git cat-file -e'),
1319
+ });
1320
+ }, 15_000);
1004
1321
  it('records the dedicated child workspace for queued no-session invocations', async () => {
1005
1322
  const { workspace: mainWorkspace, teamRun, members } = await createTeamRunFixture({
1006
1323
  memberCapabilities: [writeCapabilities],
@@ -1299,6 +1616,86 @@ describe('TeamSchedulerService', () => {
1299
1616
  status: 'RUNNING',
1300
1617
  });
1301
1618
  });
1619
+ it('does not resume targeted requests across different targetHeadSha values', async () => {
1620
+ const { workspace, teamRun, members } = await createTeamRunFixture({
1621
+ sessionPolicies: ['resume_last'],
1622
+ });
1623
+ const previousRequest = await createWorkRequest({
1624
+ teamRunId: teamRun.id,
1625
+ targetMemberId: members[0].id,
1626
+ status: 'STARTED',
1627
+ target: {
1628
+ targetKind: 'WORKSPACE_COMMIT',
1629
+ targetPurpose: 'REVIEW',
1630
+ targetSourceWorkspaceId: workspace.id,
1631
+ targetHeadSha: '1'.repeat(40),
1632
+ targetBranchName: workspace.branchName,
1633
+ },
1634
+ });
1635
+ const previousSession = await prisma.session.create({
1636
+ data: {
1637
+ workspaceId: workspace.id,
1638
+ agentType: AgentType.CODEX,
1639
+ providerId: members[0].providerId,
1640
+ prompt: 'previous prompt',
1641
+ status: 'COMPLETED',
1642
+ logSnapshot: JSON.stringify({ sessionId: 'agent-native-session-previous-target', entries: [] }),
1643
+ },
1644
+ });
1645
+ await prisma.agentInvocation.create({
1646
+ data: {
1647
+ teamRunId: teamRun.id,
1648
+ workRequestId: previousRequest.id,
1649
+ memberId: members[0].id,
1650
+ workspaceId: workspace.id,
1651
+ sessionId: previousSession.id,
1652
+ targetKind: 'WORKSPACE_COMMIT',
1653
+ targetPurpose: 'REVIEW',
1654
+ targetSourceWorkspaceId: workspace.id,
1655
+ targetHeadSha: '1'.repeat(40),
1656
+ targetBranchName: workspace.branchName,
1657
+ targetSyncStatus: 'SYNCED',
1658
+ status: 'COMPLETED',
1659
+ },
1660
+ });
1661
+ const nextRequest = await createWorkRequest({
1662
+ teamRunId: teamRun.id,
1663
+ targetMemberId: members[0].id,
1664
+ instruction: 'Review a different target',
1665
+ target: {
1666
+ targetKind: 'WORKSPACE_COMMIT',
1667
+ targetPurpose: 'REVIEW',
1668
+ targetSourceWorkspaceId: workspace.id,
1669
+ targetHeadSha: '2'.repeat(40),
1670
+ targetBranchName: workspace.branchName,
1671
+ },
1672
+ });
1673
+ const sessionManager = createSessionManagerMock();
1674
+ service = new TeamSchedulerService(lockService, {
1675
+ workspaceService: {
1676
+ create: vi.fn(),
1677
+ getOrCreateDedicatedWorkspace: vi.fn(async () => workspace),
1678
+ prepareTargetedExecutionWorkspace: vi.fn(async () => ({
1679
+ executionBranch: 'target-review-branch',
1680
+ })),
1681
+ },
1682
+ sessionManager,
1683
+ getProviderById: createProviderLookup(),
1684
+ });
1685
+ await prisma.teamMember.update({
1686
+ where: { id: members[0].id },
1687
+ data: { workspacePolicy: 'dedicated' },
1688
+ });
1689
+ const invocations = await service.startNextSessions(teamRun.id);
1690
+ expect(invocations).toHaveLength(1);
1691
+ expect(invocations[0]).toMatchObject({
1692
+ workRequestId: nextRequest.id,
1693
+ targetHeadSha: '2'.repeat(40),
1694
+ targetSyncStatus: 'SYNCED',
1695
+ });
1696
+ expect(sessionManager.start).toHaveBeenCalledWith(invocations[0].sessionId);
1697
+ expect(sessionManager.startFollowUp).not.toHaveBeenCalled();
1698
+ });
1302
1699
  it('starts new_per_request members without resuming previous native context', async () => {
1303
1700
  const { workspace, teamRun, members } = await createTeamRunFixture({
1304
1701
  sessionPolicies: ['new_per_request'],
@@ -1915,7 +2312,7 @@ describe('TeamSchedulerService', () => {
1915
2312
  status: 'FAILED',
1916
2313
  });
1917
2314
  await expect(prisma.workRequest.findUnique({ where: { id: request.id } })).resolves.toMatchObject({
1918
- status: 'STARTED',
2315
+ status: 'FAILED',
1919
2316
  });
1920
2317
  await expect(service.startNextSessions(teamRun.id)).resolves.toEqual([]);
1921
2318
  });
@@ -1936,7 +2333,7 @@ describe('TeamSchedulerService', () => {
1936
2333
  });
1937
2334
  await expect(service.startNextSessions(teamRun.id)).resolves.toEqual([]);
1938
2335
  await expect(prisma.workRequest.findUnique({ where: { id: request.id } })).resolves.toMatchObject({
1939
- status: 'STARTED',
2336
+ status: 'FAILED',
1940
2337
  });
1941
2338
  await expect(prisma.agentInvocation.findFirst({ where: { workRequestId: request.id } })).resolves.toMatchObject({
1942
2339
  status: 'FAILED',
@@ -1988,7 +2385,7 @@ describe('TeamSchedulerService', () => {
1988
2385
  sessionId: expect.any(String),
1989
2386
  });
1990
2387
  await expect(prisma.workRequest.findUnique({ where: { id: missingProviderRequest.id } })).resolves.toMatchObject({
1991
- status: 'STARTED',
2388
+ status: 'FAILED',
1992
2389
  });
1993
2390
  await expect(prisma.agentInvocation.findFirst({
1994
2391
  where: { workRequestId: missingProviderRequest.id },
@@ -2004,9 +2401,10 @@ describe('TeamSchedulerService', () => {
2004
2401
  expect(lockService.listLocks()).toEqual([]);
2005
2402
  });
2006
2403
  it('marks invocation and session failed and releases locks when session start fails', async () => {
2007
- const { teamRun, members } = await createTeamRunFixture({
2404
+ const { task, teamRun, members } = await createTeamRunFixture({
2008
2405
  memberCapabilities: [writeCapabilities],
2009
2406
  withWorkspace: false,
2407
+ taskStatus: TaskStatus.IN_PROGRESS,
2010
2408
  });
2011
2409
  const request = await createWorkRequest({
2012
2410
  teamRunId: teamRun.id,
@@ -2031,7 +2429,13 @@ describe('TeamSchedulerService', () => {
2031
2429
  status: 'FAILED',
2032
2430
  });
2033
2431
  await expect(prisma.workRequest.findUnique({ where: { id: request.id } })).resolves.toMatchObject({
2034
- status: 'STARTED',
2432
+ status: 'FAILED',
2433
+ });
2434
+ await expect(prisma.task.findUnique({ where: { id: task.id } })).resolves.toMatchObject({
2435
+ status: TaskStatus.IN_REVIEW,
2436
+ });
2437
+ await expect(prisma.teamRun.findUnique({ where: { id: teamRun.id } })).resolves.toMatchObject({
2438
+ reviewReason: 'TEAM_QUIESCENT',
2035
2439
  });
2036
2440
  await expect(service.startNextSessions(teamRun.id)).resolves.toEqual([]);
2037
2441
  await expect(prisma.agentInvocation.count({ where: { workRequestId: request.id } })).resolves.toBe(1);