github-issue-tower-defence-management 1.174.2 → 1.175.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.
- package/CHANGELOG.md +14 -0
- package/bin/adapter/entry-points/console/consoleDoneStore.js +0 -2
- package/bin/adapter/entry-points/console/consoleDoneStore.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleTabNames.js +0 -1
- package/bin/adapter/entry-points/console/consoleTabNames.js.map +1 -1
- package/bin/adapter/entry-points/console/dashboardComposeService.js +2 -4
- package/bin/adapter/entry-points/console/dashboardComposeService.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/{index-g4SqIzCh.js → index-BhDothvr.js} +1 -1
- package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/bin/domain/entities/WorkflowStatus.js +1 -6
- package/bin/domain/entities/WorkflowStatus.js.map +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +4 -5
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js +0 -39
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +4 -5
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js +15 -1
- package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js.map +1 -1
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +0 -2
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
- package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js +2 -3
- package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js.map +1 -1
- package/bin/domain/usecases/dashboard/GenerateDashboardRowUseCase.js +0 -1
- package/bin/domain/usecases/dashboard/GenerateDashboardRowUseCase.js.map +1 -1
- package/bin/domain/usecases/findLastAgentDeclaringReport.js +12 -0
- package/bin/domain/usecases/findLastAgentDeclaringReport.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/entry-points/console/consoleDoneStore.ts +0 -2
- package/src/adapter/entry-points/console/consoleTabNames.ts +0 -1
- package/src/adapter/entry-points/console/dashboardComposeService.test.ts +4 -8
- package/src/adapter/entry-points/console/dashboardComposeService.ts +1 -3
- package/src/adapter/entry-points/console/dashboardEmitterComposerKey.test.ts +12 -17
- package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +4 -32
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +1 -18
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +3 -7
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +2 -4
- package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOperationMenu.test.tsx +1 -1
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts +6 -8
- package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.test.ts +8 -17
- package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +0 -2
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +3 -3
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +5 -6
- package/src/adapter/entry-points/console/ui-dist/assets/{index-g4SqIzCh.js → index-BhDothvr.js} +1 -1
- package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/src/adapter/entry-points/console/webServer.test.ts +4 -6
- package/src/adapter/entry-points/handlers/consoleListsWriter.test.ts +30 -26
- package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +5 -6
- package/src/domain/entities/WorkflowStatus.ts +0 -5
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +32 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +7 -8
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.test.ts +198 -863
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts +0 -68
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +8 -11
- package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +89 -51
- package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +30 -2
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +62 -72
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +0 -8
- package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +19 -28
- package/src/domain/usecases/dashboard/ComposeDashboardUseCase.ts +2 -3
- package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.test.ts +11 -12
- package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.ts +0 -3
- package/src/domain/usecases/findLastAgentDeclaringReport.test.ts +71 -0
- package/src/domain/usecases/findLastAgentDeclaringReport.ts +17 -0
- package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.test.ts +2 -2
- package/types/adapter/entry-points/console/consoleDoneStore.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleTabNames.d.ts.map +1 -1
- package/types/adapter/entry-points/console/dashboardComposeService.d.ts.map +1 -1
- package/types/domain/entities/WorkflowStatus.d.ts +0 -1
- package/types/domain/entities/WorkflowStatus.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts +1 -0
- package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts.map +1 -1
- package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts +1 -2
- package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
- package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts.map +1 -1
- package/types/domain/usecases/dashboard/GenerateDashboardRowUseCase.d.ts +0 -1
- package/types/domain/usecases/dashboard/GenerateDashboardRowUseCase.d.ts.map +1 -1
- package/types/domain/usecases/findLastAgentDeclaringReport.d.ts +5 -0
- package/types/domain/usecases/findLastAgentDeclaringReport.d.ts.map +1 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>TDPM Console</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-BhDothvr.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-Bh2slMtk.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -83,7 +83,7 @@ describe('webServer pure helpers', () => {
|
|
|
83
83
|
expect(isConsoleAppRoute('/projects/acme/workflow-blocker')).toBe(true);
|
|
84
84
|
expect(isConsoleAppRoute('/projects/acme/prs')).toBe(true);
|
|
85
85
|
expect(isConsoleAppRoute('/projects/globex/triage')).toBe(true);
|
|
86
|
-
expect(isConsoleAppRoute('/projects/initech/
|
|
86
|
+
expect(isConsoleAppRoute('/projects/initech/todo-by-human')).toBe(true);
|
|
87
87
|
expect(isConsoleAppRoute('/projects/umbrella/failed-preparation')).toBe(
|
|
88
88
|
true,
|
|
89
89
|
);
|
|
@@ -1473,7 +1473,6 @@ describe('webServer dashboard /tdpm.txt route integration', () => {
|
|
|
1473
1473
|
JSON.stringify({
|
|
1474
1474
|
pjcode: 'acme',
|
|
1475
1475
|
capturedAt: '2026-06-26T00:00:00.000Z',
|
|
1476
|
-
unread: 3,
|
|
1477
1476
|
todo: 1,
|
|
1478
1477
|
qc: 2,
|
|
1479
1478
|
fail: 0,
|
|
@@ -1488,7 +1487,6 @@ describe('webServer dashboard /tdpm.txt route integration', () => {
|
|
|
1488
1487
|
JSON.stringify({
|
|
1489
1488
|
pjcode: 'initech',
|
|
1490
1489
|
capturedAt: '2026-06-26T00:00:00.000Z',
|
|
1491
|
-
unread: 0,
|
|
1492
1490
|
todo: 0,
|
|
1493
1491
|
qc: 0,
|
|
1494
1492
|
fail: 0,
|
|
@@ -1532,9 +1530,9 @@ describe('webServer dashboard /tdpm.txt route integration', () => {
|
|
|
1532
1530
|
const expectedComposed =
|
|
1533
1531
|
'<tt>M55% C62% D89% cy14</tt><br>\n' +
|
|
1534
1532
|
'<tt>LA 16 23 40</tt><br>\n' +
|
|
1535
|
-
'<tt>pj
|
|
1536
|
-
'<tt>🟢ac
|
|
1537
|
-
'<tt>🟢in 0 0 0 0
|
|
1533
|
+
'<tt>pj tdo aqc fal prp aws dep</tt><br>\n' +
|
|
1534
|
+
'<tt>🟢ac 1 2 0 0 4 1</tt><br>\n' +
|
|
1535
|
+
'<tt>🟢in 0 0 0 0 2 0</tt><br>\n' +
|
|
1538
1536
|
'<tt></tt><br>\n' +
|
|
1539
1537
|
'<tt>🟢alice 10% 0d01h00 12% 5d00h00 2 1</tt><br>\n';
|
|
1540
1538
|
|
|
@@ -38,7 +38,6 @@ const project: Project = {
|
|
|
38
38
|
name: 'Status',
|
|
39
39
|
fieldId: 'status-field',
|
|
40
40
|
statuses: [
|
|
41
|
-
option('st-unread', 'Unread', 'ORANGE'),
|
|
42
41
|
option('st-aw', 'Awaiting Workspace', 'BLUE'),
|
|
43
42
|
option('st-aqc', 'Awaiting Quality Check', 'GREEN'),
|
|
44
43
|
],
|
|
@@ -93,7 +92,7 @@ describe('writeConsoleLists', () => {
|
|
|
93
92
|
pjcode: 'demo',
|
|
94
93
|
assigneeLogin: ASSIGNEE,
|
|
95
94
|
project,
|
|
96
|
-
issues: [makeIssue({ status: '
|
|
95
|
+
issues: [makeIssue({ status: 'Todo by human' })],
|
|
97
96
|
generatedAt: '2026-06-14T07:22:33Z',
|
|
98
97
|
});
|
|
99
98
|
|
|
@@ -101,7 +100,6 @@ describe('writeConsoleLists', () => {
|
|
|
101
100
|
'workflow-blocker',
|
|
102
101
|
'prs',
|
|
103
102
|
'triage',
|
|
104
|
-
'unread',
|
|
105
103
|
'failed-preparation',
|
|
106
104
|
'todo-by-human',
|
|
107
105
|
'todo-by-agent',
|
|
@@ -198,11 +196,13 @@ describe('writeConsoleLists', () => {
|
|
|
198
196
|
pjcode: 'demo',
|
|
199
197
|
assigneeLogin: ASSIGNEE,
|
|
200
198
|
project,
|
|
201
|
-
issues: [makeIssue({ status: '
|
|
199
|
+
issues: [makeIssue({ status: 'Todo by human' })],
|
|
202
200
|
generatedAt: '2026-06-14T07:22:33Z',
|
|
203
201
|
});
|
|
204
202
|
|
|
205
|
-
const raw: unknown = JSON.parse(
|
|
203
|
+
const raw: unknown = JSON.parse(
|
|
204
|
+
fs.readFileSync(tabFile('todo-by-human'), 'utf8'),
|
|
205
|
+
);
|
|
206
206
|
expect(isRecord(raw)).toBe(true);
|
|
207
207
|
const items: unknown = isRecord(raw) ? raw.items : undefined;
|
|
208
208
|
expect(isUnknownArray(items)).toBe(true);
|
|
@@ -229,7 +229,7 @@ describe('writeConsoleLists', () => {
|
|
|
229
229
|
pjcode: 'demo',
|
|
230
230
|
assigneeLogin: ASSIGNEE,
|
|
231
231
|
project,
|
|
232
|
-
issues: [makeIssue({ status: '
|
|
232
|
+
issues: [makeIssue({ status: 'Todo by human' })],
|
|
233
233
|
});
|
|
234
234
|
expect(fs.readdirSync(outDir)).toHaveLength(0);
|
|
235
235
|
});
|
|
@@ -240,7 +240,7 @@ describe('writeConsoleLists', () => {
|
|
|
240
240
|
pjcode: '',
|
|
241
241
|
assigneeLogin: ASSIGNEE,
|
|
242
242
|
project,
|
|
243
|
-
issues: [makeIssue({ status: '
|
|
243
|
+
issues: [makeIssue({ status: 'Todo by human' })],
|
|
244
244
|
});
|
|
245
245
|
expect(fs.readdirSync(outDir)).toHaveLength(0);
|
|
246
246
|
});
|
|
@@ -251,24 +251,26 @@ describe('writeConsoleLists', () => {
|
|
|
251
251
|
pjcode: 'demo',
|
|
252
252
|
assigneeLogin: null,
|
|
253
253
|
project,
|
|
254
|
-
issues: [makeIssue({ status: '
|
|
254
|
+
issues: [makeIssue({ status: 'Todo by human' })],
|
|
255
255
|
});
|
|
256
256
|
expect(fs.readdirSync(outDir)).toHaveLength(0);
|
|
257
257
|
});
|
|
258
258
|
|
|
259
|
-
const
|
|
259
|
+
const regenerateTodoByHuman = (): void => {
|
|
260
260
|
writeConsoleLists({
|
|
261
261
|
consoleDataOutputDir: outDir,
|
|
262
262
|
pjcode: 'demo',
|
|
263
263
|
assigneeLogin: ASSIGNEE,
|
|
264
264
|
project,
|
|
265
|
-
issues: [makeIssue({ status: '
|
|
265
|
+
issues: [makeIssue({ status: 'Todo by human', itemId: 'item-1' })],
|
|
266
266
|
generatedAt: '2026-06-14T07:22:33Z',
|
|
267
267
|
});
|
|
268
268
|
};
|
|
269
269
|
|
|
270
|
-
const
|
|
271
|
-
const route = parseConsoleDataRoute(
|
|
270
|
+
const todoByHumanServedItemCount = (): number => {
|
|
271
|
+
const route = parseConsoleDataRoute(
|
|
272
|
+
'projects/demo/todo-by-human/list.json',
|
|
273
|
+
);
|
|
272
274
|
if (route === null) {
|
|
273
275
|
throw new Error('route should not be null');
|
|
274
276
|
}
|
|
@@ -279,7 +281,7 @@ describe('writeConsoleLists', () => {
|
|
|
279
281
|
};
|
|
280
282
|
|
|
281
283
|
it('resets the done file of every tab to an empty record on regeneration', () => {
|
|
282
|
-
|
|
284
|
+
regenerateTodoByHuman();
|
|
283
285
|
|
|
284
286
|
for (const tab of CONSOLE_DONE_TAB_NAMES) {
|
|
285
287
|
const doneFile = path.join(outDir, 'demo', tab, '.done.json');
|
|
@@ -291,32 +293,34 @@ describe('writeConsoleLists', () => {
|
|
|
291
293
|
|
|
292
294
|
it('clears a pre-existing accumulated done file on regeneration', () => {
|
|
293
295
|
for (const id of ['PVTI_1', 'PVTI_2', 'PVTI_3']) {
|
|
294
|
-
recordDoneProjectItemId(outDir, 'demo', '
|
|
296
|
+
recordDoneProjectItemId(outDir, 'demo', 'todo-by-human', id);
|
|
295
297
|
}
|
|
296
|
-
expect(
|
|
298
|
+
expect(
|
|
299
|
+
readDoneProjectItemIds(outDir, 'demo', 'todo-by-human'),
|
|
300
|
+
).toHaveLength(3);
|
|
297
301
|
|
|
298
|
-
|
|
302
|
+
regenerateTodoByHuman();
|
|
299
303
|
|
|
300
|
-
expect(readDoneProjectItemIds(outDir, 'demo', '
|
|
304
|
+
expect(readDoneProjectItemIds(outDir, 'demo', 'todo-by-human')).toEqual([]);
|
|
301
305
|
});
|
|
302
306
|
|
|
303
307
|
it('serves the full list after regeneration despite a prior accumulated done record', () => {
|
|
304
|
-
recordDoneProjectItemId(outDir, 'demo', '
|
|
308
|
+
recordDoneProjectItemId(outDir, 'demo', 'todo-by-human', 'item-1');
|
|
305
309
|
|
|
306
|
-
|
|
310
|
+
regenerateTodoByHuman();
|
|
307
311
|
|
|
308
|
-
expect(
|
|
312
|
+
expect(todoByHumanServedItemCount()).toBe(1);
|
|
309
313
|
});
|
|
310
314
|
|
|
311
315
|
it('re-hides an item recorded as done until the next regeneration bounds it to one cycle', () => {
|
|
312
|
-
|
|
313
|
-
expect(
|
|
316
|
+
regenerateTodoByHuman();
|
|
317
|
+
expect(todoByHumanServedItemCount()).toBe(1);
|
|
314
318
|
|
|
315
|
-
recordDoneProjectItemId(outDir, 'demo', '
|
|
316
|
-
expect(
|
|
319
|
+
recordDoneProjectItemId(outDir, 'demo', 'todo-by-human', 'item-1');
|
|
320
|
+
expect(todoByHumanServedItemCount()).toBe(0);
|
|
317
321
|
|
|
318
|
-
|
|
319
|
-
expect(
|
|
322
|
+
regenerateTodoByHuman();
|
|
323
|
+
expect(todoByHumanServedItemCount()).toBe(1);
|
|
320
324
|
});
|
|
321
325
|
});
|
|
322
326
|
|
|
@@ -60,7 +60,7 @@ describe('writeDashboardRow', () => {
|
|
|
60
60
|
pjcode: 'ac',
|
|
61
61
|
assigneeLogin: ASSIGNEE,
|
|
62
62
|
issues: [
|
|
63
|
-
makeIssue({ status: '
|
|
63
|
+
makeIssue({ status: 'Awaiting Workspace' }),
|
|
64
64
|
makeIssue({ status: 'Awaiting Quality Check' }),
|
|
65
65
|
],
|
|
66
66
|
generatedAt: '2026-06-26T12:00:00.000Z',
|
|
@@ -70,12 +70,11 @@ describe('writeDashboardRow', () => {
|
|
|
70
70
|
const expected: DashboardRowFile = {
|
|
71
71
|
pjcode: 'ac',
|
|
72
72
|
capturedAt: '2026-06-26T12:00:00.000Z',
|
|
73
|
-
unread: 1,
|
|
74
73
|
todo: 0,
|
|
75
74
|
qc: 1,
|
|
76
75
|
fail: 0,
|
|
77
76
|
pr: 0,
|
|
78
|
-
ws:
|
|
77
|
+
ws: 1,
|
|
79
78
|
dep: 0,
|
|
80
79
|
blocker: 0,
|
|
81
80
|
};
|
|
@@ -87,7 +86,7 @@ describe('writeDashboardRow', () => {
|
|
|
87
86
|
dashboardDataDir: null,
|
|
88
87
|
pjcode: 'ac',
|
|
89
88
|
assigneeLogin: ASSIGNEE,
|
|
90
|
-
issues: [makeIssue({ status: '
|
|
89
|
+
issues: [makeIssue({ status: 'Awaiting Workspace' })],
|
|
91
90
|
});
|
|
92
91
|
|
|
93
92
|
expect(fs.readdirSync(dir)).toEqual([]);
|
|
@@ -98,13 +97,13 @@ describe('writeDashboardRow', () => {
|
|
|
98
97
|
dashboardDataDir: dir,
|
|
99
98
|
pjcode: null,
|
|
100
99
|
assigneeLogin: ASSIGNEE,
|
|
101
|
-
issues: [makeIssue({ status: '
|
|
100
|
+
issues: [makeIssue({ status: 'Awaiting Workspace' })],
|
|
102
101
|
});
|
|
103
102
|
writeDashboardRow({
|
|
104
103
|
dashboardDataDir: dir,
|
|
105
104
|
pjcode: 'ac',
|
|
106
105
|
assigneeLogin: null,
|
|
107
|
-
issues: [makeIssue({ status: '
|
|
106
|
+
issues: [makeIssue({ status: 'Awaiting Workspace' })],
|
|
108
107
|
});
|
|
109
108
|
|
|
110
109
|
expect(fs.readdirSync(dir)).toEqual([]);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { FieldOption } from './Project';
|
|
2
2
|
|
|
3
|
-
export const DEFAULT_STATUS_NAME = 'Unread';
|
|
4
3
|
export const AWAITING_WORKSPACE_STATUS_NAME = 'Awaiting Workspace';
|
|
5
4
|
export const PREPARATION_STATUS_NAME = 'Preparation';
|
|
6
5
|
export const FAILED_PREPARATION_STATUS_NAME = 'Failed Preparation';
|
|
@@ -24,10 +23,6 @@ export type WorkflowStatusDefinition = {
|
|
|
24
23
|
};
|
|
25
24
|
|
|
26
25
|
export const REQUIRED_WORKFLOW_STATUSES: WorkflowStatusDefinition[] = [
|
|
27
|
-
{
|
|
28
|
-
name: DEFAULT_STATUS_NAME,
|
|
29
|
-
color: 'ORANGE',
|
|
30
|
-
},
|
|
31
26
|
{
|
|
32
27
|
name: AWAITING_WORKSPACE_STATUS_NAME,
|
|
33
28
|
color: 'BLUE',
|
|
@@ -3728,6 +3728,38 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
|
|
|
3728
3728
|
);
|
|
3729
3729
|
});
|
|
3730
3730
|
|
|
3731
|
+
it('calls setIssueAgentField when a later bot comment carries no declaration of its own', async () => {
|
|
3732
|
+
const issue = createMockIssue({ status: 'Preparation' });
|
|
3733
|
+
const projectWithAgent = makeProjectWithAgent();
|
|
3734
|
+
mockProjectRepository.getByUrl.mockResolvedValue(projectWithAgent);
|
|
3735
|
+
mockIssueRepository.get.mockResolvedValue(issue);
|
|
3736
|
+
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
3737
|
+
createMockComment({
|
|
3738
|
+
content:
|
|
3739
|
+
'From: :robot: agent (model)\n```json\n{"nextStep": "do something", "nextStepAgent": "impl"}\n```',
|
|
3740
|
+
}),
|
|
3741
|
+
createMockComment({
|
|
3742
|
+
content:
|
|
3743
|
+
'From: :robot: agent (model)\n\n## PR URL\nhttps://github.com/user/repo/pull/2\n',
|
|
3744
|
+
}),
|
|
3745
|
+
]);
|
|
3746
|
+
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
3747
|
+
|
|
3748
|
+
await useCase.run({
|
|
3749
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
3750
|
+
issueUrl: 'https://github.com/user/repo/issues/1',
|
|
3751
|
+
thresholdForAutoReject: 3,
|
|
3752
|
+
workflowBlockerResolvedWebhookUrl: null,
|
|
3753
|
+
allowedIssueAuthors: null,
|
|
3754
|
+
});
|
|
3755
|
+
|
|
3756
|
+
expect(mockIssueRepository.setIssueAgentField).toHaveBeenCalledWith(
|
|
3757
|
+
'https://github.com/user/repo/issues/1',
|
|
3758
|
+
projectWithAgent,
|
|
3759
|
+
'opt-impl',
|
|
3760
|
+
);
|
|
3761
|
+
});
|
|
3762
|
+
|
|
3731
3763
|
it('creates a new agent option and calls setIssueAgentField when nextStepAgent is not an existing option', async () => {
|
|
3732
3764
|
const issue = createMockIssue({ status: 'Preparation' });
|
|
3733
3765
|
const projectWithAgent = makeProjectWithAgent();
|
|
@@ -28,6 +28,7 @@ import { Issue } from '../entities/Issue';
|
|
|
28
28
|
import { Project } from '../entities/Project';
|
|
29
29
|
import { ensureAgentOptionAndGetId } from './ensureAgentOptionAndGetId';
|
|
30
30
|
import { extractNextStepAgent } from './extractNextStepAgent';
|
|
31
|
+
import { findLastAgentDeclaringReport } from './findLastAgentDeclaringReport';
|
|
31
32
|
import { issueReactivationTriggerIsPending } from './issueReactivationTriggerIsPending';
|
|
32
33
|
import { normalizeReportBody } from './normalizeReportBody';
|
|
33
34
|
|
|
@@ -223,14 +224,12 @@ export class NotifyFinishedIssuePreparationUseCase {
|
|
|
223
224
|
const isTrustedAuthor = (author: string): boolean =>
|
|
224
225
|
this.isAuthorTrusted(author, params.allowedIssueAuthors ?? null);
|
|
225
226
|
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
)
|
|
232
|
-
const nextStepAgent = lastTrustedBotComment
|
|
233
|
-
? extractNextStepAgent(lastTrustedBotComment.content)
|
|
227
|
+
const lastAgentDeclaringReport = findLastAgentDeclaringReport(
|
|
228
|
+
comments,
|
|
229
|
+
isTrustedAuthor,
|
|
230
|
+
);
|
|
231
|
+
const nextStepAgent = lastAgentDeclaringReport
|
|
232
|
+
? extractNextStepAgent(lastAgentDeclaringReport.content)
|
|
234
233
|
: null;
|
|
235
234
|
if (nextStepAgent !== null) {
|
|
236
235
|
const agentOptionId = await this.ensureAgentOptionAndGetId(
|