agent-tower 0.5.1-beta.2 → 0.5.2-beta.0

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 (133) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +4 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/core/container.d.ts +2 -0
  5. package/dist/core/container.d.ts.map +1 -1
  6. package/dist/core/container.js +8 -0
  7. package/dist/core/container.js.map +1 -1
  8. package/dist/executors/__tests__/codex.executor.test.js +348 -7
  9. package/dist/executors/__tests__/codex.executor.test.js.map +1 -1
  10. package/dist/executors/codex.executor.d.ts +18 -1
  11. package/dist/executors/codex.executor.d.ts.map +1 -1
  12. package/dist/executors/codex.executor.js +75 -7
  13. package/dist/executors/codex.executor.js.map +1 -1
  14. package/dist/routes/__tests__/tasks.test.js +37 -0
  15. package/dist/routes/__tests__/tasks.test.js.map +1 -1
  16. package/dist/routes/sessions.d.ts.map +1 -1
  17. package/dist/routes/sessions.js +12 -0
  18. package/dist/routes/sessions.js.map +1 -1
  19. package/dist/routes/tasks.js +2 -2
  20. package/dist/routes/tasks.js.map +1 -1
  21. package/dist/services/__tests__/project.service.test.d.ts +2 -0
  22. package/dist/services/__tests__/project.service.test.d.ts.map +1 -0
  23. package/dist/services/__tests__/project.service.test.js +62 -0
  24. package/dist/services/__tests__/project.service.test.js.map +1 -0
  25. package/dist/services/__tests__/session-manager.team-run.test.js +98 -0
  26. package/dist/services/__tests__/session-manager.team-run.test.js.map +1 -1
  27. package/dist/services/__tests__/task.service.test.js +352 -38
  28. package/dist/services/__tests__/task.service.test.js.map +1 -1
  29. package/dist/services/__tests__/team-reconciler.service.test.js +68 -0
  30. package/dist/services/__tests__/team-reconciler.service.test.js.map +1 -1
  31. package/dist/services/__tests__/team-run.service.test.js +47 -1
  32. package/dist/services/__tests__/team-run.service.test.js.map +1 -1
  33. package/dist/services/__tests__/team-scheduler.service.test.js +49 -0
  34. package/dist/services/__tests__/team-scheduler.service.test.js.map +1 -1
  35. package/dist/services/__tests__/workspace.service.test.js +102 -0
  36. package/dist/services/__tests__/workspace.service.test.js.map +1 -1
  37. package/dist/services/deleted-task-guard.d.ts +11 -0
  38. package/dist/services/deleted-task-guard.d.ts.map +1 -0
  39. package/dist/services/deleted-task-guard.js +10 -0
  40. package/dist/services/deleted-task-guard.js.map +1 -0
  41. package/dist/services/project.service.d.ts +1 -0
  42. package/dist/services/project.service.d.ts.map +1 -1
  43. package/dist/services/project.service.js +1 -1
  44. package/dist/services/project.service.js.map +1 -1
  45. package/dist/services/session-manager.d.ts +47 -1
  46. package/dist/services/session-manager.d.ts.map +1 -1
  47. package/dist/services/session-manager.js +124 -35
  48. package/dist/services/session-manager.js.map +1 -1
  49. package/dist/services/task-cleanup.service.d.ts +46 -0
  50. package/dist/services/task-cleanup.service.d.ts.map +1 -0
  51. package/dist/services/task-cleanup.service.js +202 -0
  52. package/dist/services/task-cleanup.service.js.map +1 -0
  53. package/dist/services/task.service.d.ts +15 -7
  54. package/dist/services/task.service.d.ts.map +1 -1
  55. package/dist/services/task.service.js +136 -63
  56. package/dist/services/task.service.js.map +1 -1
  57. package/dist/services/team-reconciler.service.d.ts.map +1 -1
  58. package/dist/services/team-reconciler.service.js +21 -1
  59. package/dist/services/team-reconciler.service.js.map +1 -1
  60. package/dist/services/team-run.service.d.ts.map +1 -1
  61. package/dist/services/team-run.service.js +15 -1
  62. package/dist/services/team-run.service.js.map +1 -1
  63. package/dist/services/team-scheduler.service.d.ts +3 -1
  64. package/dist/services/team-scheduler.service.d.ts.map +1 -1
  65. package/dist/services/team-scheduler.service.js +16 -0
  66. package/dist/services/team-scheduler.service.js.map +1 -1
  67. package/dist/services/workspace.service.d.ts +8 -0
  68. package/dist/services/workspace.service.d.ts.map +1 -1
  69. package/dist/services/workspace.service.js +70 -12
  70. package/dist/services/workspace.service.js.map +1 -1
  71. package/dist/web/assets/AgentDemoPage-CWcu7-P7.js +1 -0
  72. package/dist/web/assets/{DemoPage-DVt_gGQE.js → DemoPage-6hMli_sP.js} +3 -3
  73. package/dist/web/assets/GeneralSettingsPage-DUaFSgCY.js +1 -0
  74. package/dist/web/assets/MemberAvatar-S-eJAdWH.js +1 -0
  75. package/dist/web/assets/NotificationSettingsPage-Cl5x8F4G.js +1 -0
  76. package/dist/web/assets/ProfileSettingsPage-QFN9385l.js +3 -0
  77. package/dist/web/assets/ProjectKanbanPage-Dye8K5K1.js +89 -0
  78. package/dist/web/assets/ProjectSettingsPage-Do3Q1_r4.js +2 -0
  79. package/dist/web/assets/ProviderSettingsPage-DYOb33XQ.js +54 -0
  80. package/dist/web/assets/SettingsSection-D0Zzbbhp.js +1 -0
  81. package/dist/web/assets/TeamSettingsPage-Dq_DU1S8.js +1 -0
  82. package/dist/web/assets/arrow-left-D0xGRsQG.js +1 -0
  83. package/dist/web/assets/button-C-IDw2d8.js +1 -0
  84. package/dist/web/assets/check-KjbNKANU.js +1 -0
  85. package/dist/web/assets/chevron-down-C735lPj9.js +1 -0
  86. package/dist/web/assets/chevron-right-DfFiWY3R.js +1 -0
  87. package/dist/web/assets/{chevron-up-BkPAyFXE.js → chevron-up-DqGc0SsZ.js} +1 -1
  88. package/dist/web/assets/{circle-check-BmWaxH2e.js → circle-check-CSlvn06a.js} +1 -1
  89. package/dist/web/assets/{code-block-OCS4YCEC-U8rjjKMO.js → code-block-OCS4YCEC-BRT1Nrpy.js} +1 -1
  90. package/dist/web/assets/confirm-dialog-BtsxywSG.js +1 -0
  91. package/dist/web/assets/folder-picker-BuvfyaHB.js +1 -0
  92. package/dist/web/assets/index-BAz6UxmL.js +13 -0
  93. package/dist/web/assets/index-r8en4dlI.css +1 -0
  94. package/dist/web/assets/loader-circle-BLO3w-ze.js +1 -0
  95. package/dist/web/assets/{mermaid-NOHMQCX5-CfVlHQvQ.js → mermaid-NOHMQCX5-BLfGHrOE.js} +53 -53
  96. package/dist/web/assets/message-square-CIyucdyo.js +1 -0
  97. package/dist/web/assets/modal-D_VShm6D.js +1 -0
  98. package/dist/web/assets/{pencil-DvjVNKIw.js → pencil-CdJXJig-.js} +1 -1
  99. package/dist/web/assets/rotate-ccw-B42Jf1RW.js +1 -0
  100. package/dist/web/assets/{select-Xt2WadPY.js → select-kVmZCXo9.js} +1 -1
  101. package/dist/web/assets/{use-profiles-oZ63gfvO.js → use-profiles-Bvj_EW-7.js} +1 -1
  102. package/dist/web/assets/{use-providers-BVrApYJA.js → use-providers-CcFzAUyf.js} +1 -1
  103. package/dist/web/index.html +2 -2
  104. package/node_modules/@prisma/client/.prisma/client/edge.js +22 -5
  105. package/node_modules/@prisma/client/.prisma/client/index-browser.js +17 -0
  106. package/node_modules/@prisma/client/.prisma/client/index.d.ts +1534 -142
  107. package/node_modules/@prisma/client/.prisma/client/index.js +22 -5
  108. package/node_modules/@prisma/client/.prisma/client/package.json +1 -1
  109. package/node_modules/@prisma/client/.prisma/client/schema.prisma +23 -0
  110. package/node_modules/@prisma/client/.prisma/client/wasm.js +17 -0
  111. package/package.json +1 -1
  112. package/prisma/migrations/20260603000000_add_task_cleanup_jobs/migration.sql +21 -0
  113. package/prisma/schema.prisma +23 -0
  114. package/dist/web/assets/AgentDemoPage-CEWSskKz.js +0 -1
  115. package/dist/web/assets/GeneralSettingsPage-B7DbUzT6.js +0 -1
  116. package/dist/web/assets/MemberAvatar--HnaCo5f.js +0 -1
  117. package/dist/web/assets/NotificationSettingsPage-BklUEhB2.js +0 -1
  118. package/dist/web/assets/ProfileSettingsPage-Be7yYwbc.js +0 -3
  119. package/dist/web/assets/ProjectKanbanPage-BZR3HX3_.js +0 -90
  120. package/dist/web/assets/ProjectSettingsPage-Cj1h7G2-.js +0 -2
  121. package/dist/web/assets/ProviderSettingsPage-l244dDeI.js +0 -54
  122. package/dist/web/assets/TeamSettingsPage-CXp-7kqb.js +0 -1
  123. package/dist/web/assets/button-Cc_0rVdG.js +0 -1
  124. package/dist/web/assets/chevron-down-DAto5uxR.js +0 -1
  125. package/dist/web/assets/chevron-right-fcp8yUcf.js +0 -1
  126. package/dist/web/assets/confirm-dialog-D0R59Lv2.js +0 -1
  127. package/dist/web/assets/folder-picker-COVJdb7m.js +0 -1
  128. package/dist/web/assets/index-BCz-PlSG.js +0 -13
  129. package/dist/web/assets/index-BjIvVVfi.css +0 -1
  130. package/dist/web/assets/loader-circle-B0dxeUg4.js +0 -1
  131. package/dist/web/assets/modal-kzH1vcBa.js +0 -1
  132. package/dist/web/assets/upload-dtpXWuCN.js +0 -1
  133. package/dist/web/assets/utils-CkSf8FUe.js +0 -1
@@ -4,18 +4,21 @@ import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
7
+ import { AgentType } from '../../types/index.js';
7
8
  const testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-tower-task-service-'));
8
9
  const dbPath = path.join(testDir, 'test.db');
9
10
  process.env.AGENT_TOWER_DATABASE_URL = `file:${dbPath}`;
10
- const { removeWorktreeMock, deleteBranchIfSafeMock, } = vi.hoisted(() => ({
11
+ const { removeWorktreeMock, deleteBranchIfSafeMock, pruneWorktreesMock, } = vi.hoisted(() => ({
11
12
  removeWorktreeMock: vi.fn(),
12
13
  deleteBranchIfSafeMock: vi.fn(),
14
+ pruneWorktreesMock: vi.fn(),
13
15
  }));
14
16
  vi.mock('../../git/worktree.manager.js', () => ({
15
17
  WorktreeManager: vi.fn().mockImplementation(function () {
16
18
  return {
17
19
  remove: removeWorktreeMock,
18
20
  deleteBranchIfSafe: deleteBranchIfSafeMock,
21
+ prune: pruneWorktreesMock,
19
22
  };
20
23
  }),
21
24
  }));
@@ -24,6 +27,9 @@ const __dirname = path.dirname(__filename);
24
27
  const serverRoot = path.resolve(__dirname, '../../..');
25
28
  const schemaPath = path.join(serverRoot, 'prisma/schema.prisma');
26
29
  let TaskService;
30
+ let TaskCleanupService;
31
+ let WorkspaceService;
32
+ let SessionManagerClass;
27
33
  let EventBus;
28
34
  let prisma;
29
35
  describe('TaskService', () => {
@@ -34,9 +40,15 @@ describe('TaskService', () => {
34
40
  stdio: 'pipe',
35
41
  });
36
42
  const serviceModule = await import('../task.service.js');
43
+ const cleanupModule = await import('../task-cleanup.service.js');
44
+ const workspaceModule = await import('../workspace.service.js');
45
+ const sessionManagerModule = await import('../session-manager.js');
37
46
  const eventBusModule = await import('../../core/event-bus.js');
38
47
  const utilsModule = await import('../../utils/index.js');
39
48
  TaskService = serviceModule.TaskService;
49
+ TaskCleanupService = cleanupModule.TaskCleanupService;
50
+ WorkspaceService = workspaceModule.WorkspaceService;
51
+ SessionManagerClass = sessionManagerModule.SessionManager;
40
52
  EventBus = eventBusModule.EventBus;
41
53
  prisma = utilsModule.prisma;
42
54
  });
@@ -51,6 +63,8 @@ describe('TaskService', () => {
51
63
  status: 'deleted',
52
64
  branchName,
53
65
  }));
66
+ pruneWorktreesMock.mockResolvedValue(undefined);
67
+ await prisma.taskCleanupJob.deleteMany();
54
68
  await prisma.agentInvocation.deleteMany();
55
69
  await prisma.workRequest.deleteMany();
56
70
  await prisma.roomMessage.deleteMany();
@@ -90,9 +104,13 @@ describe('TaskService', () => {
90
104
  const task = await service.create(project.id, { title: ' Ship TeamRun startup ' });
91
105
  expect(task.title).toBe('Ship TeamRun startup');
92
106
  });
93
- it('deletes all associated worktrees and local branches before deleting task records', async () => {
107
+ it('marks a task deleted and enqueues a cleanup job without waiting for resource cleanup', async () => {
94
108
  const stopSessionMock = vi.fn();
95
- const service = new TaskService(new EventBus(), { stop: stopSessionMock });
109
+ const cleanupTriggerMock = vi.fn();
110
+ const eventBus = new EventBus();
111
+ const deletedEvents = [];
112
+ eventBus.on('task:deleted', (payload) => deletedEvents.push(payload));
113
+ const service = new TaskService(eventBus, { stop: stopSessionMock }, { trigger: cleanupTriggerMock });
96
114
  const project = await prisma.project.create({
97
115
  data: {
98
116
  name: 'Task delete project',
@@ -140,45 +158,318 @@ describe('TaskService', () => {
140
158
  status: 'COMPLETED',
141
159
  },
142
160
  });
143
- deleteBranchIfSafeMock.mockImplementation(async (branchName) => {
144
- await expect(prisma.task.findUnique({ where: { id: task.id } })).resolves.toMatchObject({
145
- id: task.id,
146
- });
147
- return {
148
- status: 'deleted',
149
- branchName,
150
- };
161
+ const teamRun = await prisma.teamRun.create({
162
+ data: {
163
+ taskId: task.id,
164
+ mode: 'AUTO',
165
+ },
166
+ });
167
+ const member = await prisma.teamMember.create({
168
+ data: {
169
+ teamRunId: teamRun.id,
170
+ presetId: null,
171
+ name: 'Member',
172
+ aliases: '[]',
173
+ providerId: 'provider-1',
174
+ rolePrompt: 'Role',
175
+ capabilities: '{}',
176
+ workspacePolicy: 'shared',
177
+ triggerPolicy: 'MENTION_ONLY',
178
+ sessionPolicy: 'new_per_request',
179
+ queueManagementPolicy: 'own_only',
180
+ avatar: null,
181
+ },
182
+ });
183
+ const pendingRequest = await prisma.workRequest.create({
184
+ data: {
185
+ teamRunId: teamRun.id,
186
+ requesterMemberId: null,
187
+ requesterType: 'user',
188
+ targetMemberId: member.id,
189
+ triggerMessageId: 'pending-message',
190
+ instruction: 'please approve',
191
+ status: 'PENDING_APPROVAL',
192
+ },
193
+ });
194
+ const queuedRequest = await prisma.workRequest.create({
195
+ data: {
196
+ teamRunId: teamRun.id,
197
+ requesterMemberId: null,
198
+ requesterType: 'user',
199
+ targetMemberId: member.id,
200
+ triggerMessageId: 'queued-message',
201
+ instruction: 'please run',
202
+ status: 'QUEUED',
203
+ },
204
+ });
205
+ const runningRequest = await prisma.workRequest.create({
206
+ data: {
207
+ teamRunId: teamRun.id,
208
+ requesterMemberId: null,
209
+ requesterType: 'user',
210
+ targetMemberId: member.id,
211
+ triggerMessageId: 'running-message',
212
+ instruction: 'running',
213
+ status: 'STARTED',
214
+ },
215
+ });
216
+ const runningInvocation = await prisma.agentInvocation.create({
217
+ data: {
218
+ teamRunId: teamRun.id,
219
+ workRequestId: runningRequest.id,
220
+ memberId: member.id,
221
+ workspaceId: mainWorkspace.id,
222
+ sessionId: runningSession.id,
223
+ status: 'RUNNING',
224
+ nextRoomReplyReminderAt: new Date(),
225
+ },
151
226
  });
152
227
  await expect(service.delete(task.id)).resolves.toBe(true);
153
- expect(stopSessionMock).toHaveBeenCalledTimes(1);
154
- expect(stopSessionMock).toHaveBeenCalledWith(runningSession.id);
155
- expect(removeWorktreeMock).toHaveBeenCalledTimes(2);
156
- expect(removeWorktreeMock).toHaveBeenCalledWith(mainWorkspace.worktreePath);
157
- expect(removeWorktreeMock).toHaveBeenCalledWith(memberWorkspace.worktreePath);
158
- expect(deleteBranchIfSafeMock).toHaveBeenCalledTimes(2);
159
- expect(deleteBranchIfSafeMock).toHaveBeenCalledWith(mainWorkspace.branchName, {
160
- protectedBranches: [project.mainBranch, mainWorkspace.baseBranch],
161
- });
162
- expect(deleteBranchIfSafeMock).toHaveBeenCalledWith(memberWorkspace.branchName, {
163
- protectedBranches: [project.mainBranch, memberWorkspace.baseBranch],
164
- });
165
- expect(removeWorktreeMock.mock.invocationCallOrder[0]).toBeLessThan(deleteBranchIfSafeMock.mock.invocationCallOrder[0]);
228
+ expect(stopSessionMock).not.toHaveBeenCalled();
229
+ expect(removeWorktreeMock).not.toHaveBeenCalled();
230
+ expect(deleteBranchIfSafeMock).not.toHaveBeenCalled();
231
+ expect(cleanupTriggerMock).toHaveBeenCalledTimes(1);
232
+ expect(deletedEvents).toEqual([{ taskId: task.id, projectId: project.id }]);
233
+ const deletedTask = await prisma.task.findUnique({ where: { id: task.id } });
234
+ expect(deletedTask?.deletedAt).toBeInstanceOf(Date);
235
+ await expect(prisma.workspace.count({ where: { taskId: task.id } })).resolves.toBe(2);
236
+ await expect(prisma.session.count({ where: { workspaceId: { in: [mainWorkspace.id, memberWorkspace.id] } } })).resolves.toBe(2);
237
+ await expect(prisma.workRequest.findMany({
238
+ where: { id: { in: [pendingRequest.id, queuedRequest.id, runningRequest.id] } },
239
+ orderBy: { id: 'asc' },
240
+ })).resolves.toEqual(expect.arrayContaining([
241
+ expect.objectContaining({ id: pendingRequest.id, status: 'CANCELLED' }),
242
+ expect.objectContaining({ id: queuedRequest.id, status: 'CANCELLED' }),
243
+ expect.objectContaining({ id: runningRequest.id, status: 'CANCELLED' }),
244
+ ]));
245
+ await expect(prisma.agentInvocation.findUnique({ where: { id: runningInvocation.id } })).resolves.toMatchObject({
246
+ status: 'CANCELLED',
247
+ nextRoomReplyReminderAt: null,
248
+ });
249
+ const cleanupJob = await prisma.taskCleanupJob.findFirstOrThrow({ where: { taskId: task.id } });
250
+ expect(cleanupJob).toMatchObject({
251
+ projectId: project.id,
252
+ status: 'PENDING',
253
+ attempts: 0,
254
+ });
255
+ const payload = JSON.parse(cleanupJob.payload);
256
+ expect(payload).toMatchObject({
257
+ taskId: task.id,
258
+ projectId: project.id,
259
+ project: {
260
+ repoPath: project.repoPath,
261
+ mainBranch: project.mainBranch,
262
+ },
263
+ workspaces: [
264
+ {
265
+ id: mainWorkspace.id,
266
+ branchName: mainWorkspace.branchName,
267
+ worktreePath: mainWorkspace.worktreePath,
268
+ sessions: [{ id: runningSession.id }],
269
+ },
270
+ {
271
+ id: memberWorkspace.id,
272
+ branchName: memberWorkspace.branchName,
273
+ worktreePath: memberWorkspace.worktreePath,
274
+ },
275
+ ],
276
+ });
277
+ });
278
+ it('marks deleted before reading the cleanup snapshot so new resource creation is rejected', async () => {
279
+ const service = new TaskService(new EventBus(), { stop: vi.fn() }, { trigger: vi.fn() });
280
+ const project = await prisma.project.create({
281
+ data: {
282
+ name: 'Task delete ordering project',
283
+ repoPath: testDir,
284
+ mainBranch: 'main',
285
+ },
286
+ });
287
+ const task = await prisma.task.create({
288
+ data: {
289
+ title: 'Delete ordering task',
290
+ projectId: project.id,
291
+ },
292
+ });
293
+ const existingWorkspace = await prisma.workspace.create({
294
+ data: {
295
+ taskId: task.id,
296
+ branchName: 'at/existing-before-delete',
297
+ baseBranch: 'main',
298
+ worktreePath: path.join(testDir, '.worktrees', 'at', 'existing-before-delete'),
299
+ status: 'ACTIVE',
300
+ },
301
+ });
302
+ const runningSession = await prisma.session.create({
303
+ data: {
304
+ workspaceId: existingWorkspace.id,
305
+ agentType: 'CODEX',
306
+ prompt: 'run',
307
+ status: 'RUNNING',
308
+ },
309
+ });
310
+ let releaseSnapshotRead;
311
+ const releaseSnapshotReadPromise = new Promise((resolve) => {
312
+ releaseSnapshotRead = resolve;
313
+ });
314
+ let snapshotReadStarted;
315
+ const snapshotReadStartedPromise = new Promise((resolve) => {
316
+ snapshotReadStarted = resolve;
317
+ });
318
+ let shouldDelaySnapshotRead = true;
319
+ prisma.$use(async (params, next) => {
320
+ const include = params.args?.include;
321
+ const isSnapshotRead = params.model === 'Task'
322
+ && params.action === 'findUnique'
323
+ && Boolean(include?.workspaces);
324
+ if (shouldDelaySnapshotRead && isSnapshotRead) {
325
+ shouldDelaySnapshotRead = false;
326
+ snapshotReadStarted();
327
+ await releaseSnapshotReadPromise;
328
+ }
329
+ return next(params);
330
+ });
331
+ const deletePromise = service.delete(task.id);
332
+ await snapshotReadStartedPromise;
333
+ await expect(prisma.task.findUnique({ where: { id: task.id } })).resolves.toMatchObject({
334
+ deletedAt: expect.any(Date),
335
+ });
336
+ const workspaceService = new WorkspaceService();
337
+ await expect(workspaceService.create(task.id)).rejects.toMatchObject({
338
+ code: 'NOT_FOUND',
339
+ statusCode: 404,
340
+ });
341
+ const sessionManager = new SessionManagerClass(new EventBus());
342
+ await expect(sessionManager.create(existingWorkspace.id, AgentType.CODEX, 'late session')).rejects.toMatchObject({
343
+ code: 'NOT_FOUND',
344
+ statusCode: 404,
345
+ });
346
+ releaseSnapshotRead();
347
+ await expect(deletePromise).resolves.toBe(true);
348
+ const cleanupJob = await prisma.taskCleanupJob.findFirstOrThrow({ where: { taskId: task.id } });
349
+ const payload = JSON.parse(cleanupJob.payload);
350
+ expect(payload.workspaces).toEqual(expect.arrayContaining([
351
+ expect.objectContaining({
352
+ id: existingWorkspace.id,
353
+ branchName: existingWorkspace.branchName,
354
+ worktreePath: existingWorkspace.worktreePath,
355
+ sessions: [{ id: runningSession.id }],
356
+ }),
357
+ ]));
358
+ });
359
+ it('filters deleted tasks from lists and stats', async () => {
360
+ const service = new TaskService(new EventBus(), { stop: vi.fn() });
361
+ const project = await prisma.project.create({
362
+ data: {
363
+ name: 'Task list project',
364
+ repoPath: testDir,
365
+ },
366
+ });
367
+ await prisma.task.create({
368
+ data: {
369
+ title: 'Visible task',
370
+ projectId: project.id,
371
+ },
372
+ });
373
+ await prisma.task.create({
374
+ data: {
375
+ title: 'Deleted task',
376
+ projectId: project.id,
377
+ status: 'DONE',
378
+ deletedAt: new Date(),
379
+ },
380
+ });
381
+ const list = await service.findByProjectId(project.id);
382
+ expect(list.total).toBe(1);
383
+ expect(list.data.map((task) => task.title)).toEqual(['Visible task']);
384
+ const stats = await service.getStatsByProjectId(project.id);
385
+ expect(stats.total).toBe(1);
386
+ expect(stats.done).toBe(0);
387
+ expect(stats.todo).toBe(1);
388
+ });
389
+ it('processes a cleanup job and hard-deletes task records after resources are cleaned', async () => {
390
+ const stopSessionMock = vi.fn();
391
+ const cleanupService = new TaskCleanupService({ stop: stopSessionMock });
392
+ const project = await prisma.project.create({
393
+ data: {
394
+ name: 'Task cleanup project',
395
+ repoPath: testDir,
396
+ mainBranch: 'main',
397
+ },
398
+ });
399
+ const task = await prisma.task.create({
400
+ data: {
401
+ title: 'Cleanup task resources',
402
+ projectId: project.id,
403
+ deletedAt: new Date(),
404
+ },
405
+ });
406
+ const workspace = await prisma.workspace.create({
407
+ data: {
408
+ taskId: task.id,
409
+ branchName: 'at/cleanup-branch',
410
+ baseBranch: 'main',
411
+ worktreePath: path.join(testDir, '.worktrees', 'at', 'cleanup-branch'),
412
+ status: 'ACTIVE',
413
+ },
414
+ });
415
+ const runningSession = await prisma.session.create({
416
+ data: {
417
+ workspaceId: workspace.id,
418
+ agentType: 'CODEX',
419
+ prompt: 'run',
420
+ status: 'RUNNING',
421
+ },
422
+ });
423
+ const payload = {
424
+ taskId: task.id,
425
+ projectId: project.id,
426
+ project: {
427
+ repoPath: project.repoPath,
428
+ mainBranch: project.mainBranch,
429
+ },
430
+ workspaces: [{
431
+ id: workspace.id,
432
+ worktreePath: workspace.worktreePath,
433
+ branchName: workspace.branchName,
434
+ baseBranch: workspace.baseBranch,
435
+ sessions: [{ id: runningSession.id }],
436
+ }],
437
+ };
438
+ await prisma.taskCleanupJob.create({
439
+ data: {
440
+ taskId: task.id,
441
+ projectId: project.id,
442
+ payload: JSON.stringify(payload),
443
+ },
444
+ });
445
+ await expect(cleanupService.processDueJobs()).resolves.toBe(1);
446
+ expect(stopSessionMock).toHaveBeenCalledWith(runningSession.id, { skipTeamRunReconcile: true });
447
+ expect(removeWorktreeMock).toHaveBeenCalledWith(workspace.worktreePath);
448
+ expect(deleteBranchIfSafeMock).toHaveBeenCalledWith(workspace.branchName, {
449
+ protectedBranches: [project.mainBranch, workspace.baseBranch],
450
+ });
451
+ expect(pruneWorktreesMock).toHaveBeenCalledTimes(1);
166
452
  await expect(prisma.task.findUnique({ where: { id: task.id } })).resolves.toBeNull();
167
453
  await expect(prisma.workspace.count({ where: { taskId: task.id } })).resolves.toBe(0);
168
- await expect(prisma.session.count({ where: { workspaceId: { in: [mainWorkspace.id, memberWorkspace.id] } } })).resolves.toBe(0);
454
+ await expect(prisma.taskCleanupJob.findFirst({ where: { taskId: task.id } })).resolves.toMatchObject({
455
+ status: 'COMPLETED',
456
+ attempts: 1,
457
+ lastError: null,
458
+ });
169
459
  });
170
- it('continues deleting the task when branch deletion is skipped or fails', async () => {
171
- const service = new TaskService(new EventBus(), { stop: vi.fn() });
460
+ it('records cleanup failures and schedules retry', async () => {
461
+ const cleanupService = new TaskCleanupService({ stop: vi.fn() });
172
462
  const project = await prisma.project.create({
173
463
  data: {
174
- name: 'Task delete warning project',
464
+ name: 'Task cleanup failure project',
175
465
  repoPath: testDir,
176
466
  },
177
467
  });
178
468
  const task = await prisma.task.create({
179
469
  data: {
180
- title: 'Delete task with branch warning',
470
+ title: 'Cleanup failure',
181
471
  projectId: project.id,
472
+ deletedAt: new Date(),
182
473
  },
183
474
  });
184
475
  const workspace = await prisma.workspace.create({
@@ -190,20 +481,43 @@ describe('TaskService', () => {
190
481
  status: 'ACTIVE',
191
482
  },
192
483
  });
193
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
484
+ const payload = {
485
+ taskId: task.id,
486
+ projectId: project.id,
487
+ project: {
488
+ repoPath: project.repoPath,
489
+ mainBranch: project.mainBranch,
490
+ },
491
+ workspaces: [{
492
+ id: workspace.id,
493
+ worktreePath: workspace.worktreePath,
494
+ branchName: workspace.branchName,
495
+ baseBranch: workspace.baseBranch,
496
+ sessions: [],
497
+ }],
498
+ };
499
+ const job = await prisma.taskCleanupJob.create({
500
+ data: {
501
+ taskId: task.id,
502
+ projectId: project.id,
503
+ payload: JSON.stringify(payload),
504
+ },
505
+ });
194
506
  deleteBranchIfSafeMock.mockResolvedValueOnce({
195
507
  status: 'failed',
196
508
  branchName: workspace.branchName,
197
509
  reason: 'git branch failed',
198
510
  });
199
- try {
200
- await expect(service.delete(task.id)).resolves.toBe(true);
201
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining(`Failed to delete branch ${workspace.branchName}`), 'git branch failed');
202
- await expect(prisma.task.findUnique({ where: { id: task.id } })).resolves.toBeNull();
203
- }
204
- finally {
205
- warnSpy.mockRestore();
206
- }
511
+ await expect(cleanupService.processDueJobs()).resolves.toBe(1);
512
+ await expect(prisma.task.findUnique({ where: { id: task.id } })).resolves.toMatchObject({
513
+ id: task.id,
514
+ });
515
+ await expect(prisma.taskCleanupJob.findUnique({ where: { id: job.id } })).resolves.toMatchObject({
516
+ status: 'FAILED',
517
+ attempts: 1,
518
+ lastError: expect.stringContaining('git branch failed'),
519
+ nextRetryAt: expect.any(Date),
520
+ });
207
521
  });
208
522
  });
209
523
  //# sourceMappingURL=task.service.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/task.service.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"task.service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/task.service.test.ts"],"names":[],"mappings":"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"}
@@ -513,6 +513,38 @@ describe('TeamReconcilerService', () => {
513
513
  });
514
514
  expect(scheduler.startNextSessions).toHaveBeenCalledWith(teamRun.id);
515
515
  });
516
+ it('does not start queued work when a stopped session belongs to a deleted task', async () => {
517
+ const { workspace, task, teamRun, members } = await createFixture({ taskStatus: TaskStatus.IN_PROGRESS });
518
+ const request = await createWorkRequest({ teamRunId: teamRun.id, targetMemberId: members[0].id });
519
+ const invocation = await createRunningInvocation({
520
+ teamRunId: teamRun.id,
521
+ workRequestId: request.id,
522
+ memberId: members[0].id,
523
+ workspaceId: workspace.id,
524
+ status: 'RUNNING',
525
+ });
526
+ await createWorkRequest({
527
+ teamRunId: teamRun.id,
528
+ targetMemberId: members[0].id,
529
+ status: 'QUEUED',
530
+ });
531
+ await prisma.task.update({
532
+ where: { id: task.id },
533
+ data: { deletedAt: new Date() },
534
+ });
535
+ expect(lockService.acquire(invocation.id, ['workspace:task:write'])).toBe(true);
536
+ await expect(service.handleSessionStopped(invocation.sessionId)).resolves.toBe(true);
537
+ await expect(prisma.agentInvocation.findUnique({ where: { id: invocation.id } })).resolves.toMatchObject({
538
+ status: 'CANCELLED',
539
+ nextRoomReplyReminderAt: null,
540
+ });
541
+ expect(scheduler.releaseInvocationLocks).toHaveBeenCalledWith(invocation.id);
542
+ expect(lockService.listLocks()).toEqual([]);
543
+ expect(scheduler.startNextSessions).not.toHaveBeenCalled();
544
+ await expect(prisma.task.findUnique({ where: { id: task.id } })).resolves.toMatchObject({
545
+ status: TaskStatus.IN_PROGRESS,
546
+ });
547
+ });
516
548
  it.each([
517
549
  ['queued work request', async (teamRunId, memberId) => {
518
550
  await createWorkRequest({ teamRunId, targetMemberId: memberId, status: 'QUEUED' });
@@ -2192,6 +2224,42 @@ describe('TeamReconcilerService', () => {
2192
2224
  expect(scheduler.releaseInvocationLocks).toHaveBeenCalledWith(invocation.id);
2193
2225
  expect(scheduler.startNextSessions).toHaveBeenCalledWith(teamRun.id);
2194
2226
  });
2227
+ it('SessionManager.stop can skip TeamRun reconciliation for cleanup', async () => {
2228
+ const { workspace, teamRun, members } = await createFixture({ taskStatus: TaskStatus.IN_PROGRESS });
2229
+ const request = await createWorkRequest({ teamRunId: teamRun.id, targetMemberId: members[0].id });
2230
+ const session = await prisma.session.create({
2231
+ data: {
2232
+ workspaceId: workspace.id,
2233
+ agentType: 'CODEX',
2234
+ providerId: 'provider-1',
2235
+ prompt: 'TeamRun work',
2236
+ status: 'RUNNING',
2237
+ },
2238
+ });
2239
+ const invocation = await createRunningInvocation({
2240
+ teamRunId: teamRun.id,
2241
+ workRequestId: request.id,
2242
+ memberId: members[0].id,
2243
+ workspaceId: workspace.id,
2244
+ sessionId: session.id,
2245
+ status: 'RUNNING',
2246
+ });
2247
+ await createWorkRequest({
2248
+ teamRunId: teamRun.id,
2249
+ targetMemberId: members[0].id,
2250
+ status: 'QUEUED',
2251
+ });
2252
+ const manager = new SessionManager(new EventBus(), service);
2253
+ await expect(manager.stop(session.id, { skipTeamRunReconcile: true })).resolves.toMatchObject({ id: session.id });
2254
+ await expect(prisma.session.findUnique({ where: { id: session.id } })).resolves.toMatchObject({
2255
+ status: 'CANCELLED',
2256
+ });
2257
+ await expect(prisma.agentInvocation.findUnique({ where: { id: invocation.id } })).resolves.toMatchObject({
2258
+ status: 'RUNNING',
2259
+ });
2260
+ expect(scheduler.releaseInvocationLocks).not.toHaveBeenCalled();
2261
+ expect(scheduler.startNextSessions).not.toHaveBeenCalled();
2262
+ });
2195
2263
  it('SessionManager.stop leaves solo sessions without TeamRun reconciliation', async () => {
2196
2264
  const { workspace } = await createFixture();
2197
2265
  const session = await prisma.session.create({