github-issue-tower-defence-management 1.166.6 → 1.168.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/.github/workflows/console-ui.yml +1 -0
- package/CHANGELOG.md +20 -0
- package/bin/adapter/entry-points/cli/index.js +1 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-DkAuY63u.js +86 -0
- package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/bin/adapter/entry-points/console/ui-dist/sw.js +60 -0
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -0
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +2 -26
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +19 -0
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +7 -1
- package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
- package/bin/domain/usecases/ensureAgentOptionAndGetId.js +31 -0
- package/bin/domain/usecases/ensureAgentOptionAndGetId.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/ci/consoleUiWorkflowTimeout.test.ts +61 -0
- package/src/adapter/entry-points/cli/index.test.ts +33 -0
- package/src/adapter/entry-points/cli/index.ts +1 -0
- package/src/adapter/entry-points/console/ui/public/sw.js +60 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +9 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +31 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.tsx +8 -1
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.test.ts +111 -15
- package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.ts +100 -15
- package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.test.ts +70 -1
- package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +42 -6
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +2 -0
- package/src/adapter/entry-points/console/ui/src/main.tsx +6 -0
- package/src/adapter/entry-points/console/ui-dist/assets/index-DkAuY63u.js +86 -0
- package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/src/adapter/entry-points/console/ui-dist/sw.js +60 -0
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +1 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +4 -38
- package/src/domain/usecases/StartPreparationUseCase.test.ts +199 -4
- package/src/domain/usecases/StartPreparationUseCase.ts +50 -1
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +13 -0
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +6 -1
- package/src/domain/usecases/ensureAgentOptionAndGetId.ts +47 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts +3 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
- package/types/domain/usecases/ensureAgentOptionAndGetId.d.ts +4 -0
- package/types/domain/usecases/ensureAgentOptionAndGetId.d.ts.map +1 -0
- package/bin/adapter/entry-points/console/ui-dist/assets/index-CrSqMAVR.js +0 -86
- package/src/adapter/entry-points/console/ui-dist/assets/index-CrSqMAVR.js +0 -86
|
@@ -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-DkAuY63u.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-U8I8ESZj.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const SHELL_CACHE = 'console-shell-v1';
|
|
2
|
+
|
|
3
|
+
self.addEventListener('install', (event) => {
|
|
4
|
+
event.waitUntil(caches.open(SHELL_CACHE).then((cache) => cache.add('/')));
|
|
5
|
+
self.skipWaiting();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
self.addEventListener('activate', (event) => {
|
|
9
|
+
event.waitUntil(
|
|
10
|
+
caches
|
|
11
|
+
.keys()
|
|
12
|
+
.then((names) =>
|
|
13
|
+
Promise.all(
|
|
14
|
+
names
|
|
15
|
+
.filter((name) => name !== SHELL_CACHE)
|
|
16
|
+
.map((name) => caches.delete(name)),
|
|
17
|
+
),
|
|
18
|
+
),
|
|
19
|
+
);
|
|
20
|
+
self.clients.claim();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
self.addEventListener('fetch', (event) => {
|
|
24
|
+
if (event.request.method !== 'GET') {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const url = new URL(event.request.url);
|
|
28
|
+
if (url.origin !== self.location.origin) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (
|
|
32
|
+
url.pathname.startsWith('/projects/') ||
|
|
33
|
+
url.pathname.startsWith('/api/')
|
|
34
|
+
) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
event.respondWith(
|
|
38
|
+
fetch(event.request)
|
|
39
|
+
.then((response) => {
|
|
40
|
+
if (response.ok) {
|
|
41
|
+
caches
|
|
42
|
+
.open(SHELL_CACHE)
|
|
43
|
+
.then((cache) => cache.put(event.request, response.clone()))
|
|
44
|
+
.catch((e) => console.warn('Shell cache put failed:', e));
|
|
45
|
+
}
|
|
46
|
+
return response;
|
|
47
|
+
})
|
|
48
|
+
.catch(async () => {
|
|
49
|
+
const cached = await caches.match(event.request);
|
|
50
|
+
if (cached !== undefined) {
|
|
51
|
+
return cached;
|
|
52
|
+
}
|
|
53
|
+
const root = await caches.match('/');
|
|
54
|
+
if (root !== undefined) {
|
|
55
|
+
return root;
|
|
56
|
+
}
|
|
57
|
+
return Response.error();
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
});
|
|
@@ -471,6 +471,7 @@ ${JSON.stringify(e)}
|
|
|
471
471
|
manager: input.manager,
|
|
472
472
|
codexHomeCandidates: input.startPreparation.codexHomeCandidates ?? null,
|
|
473
473
|
labelsAsLlmAgentName,
|
|
474
|
+
agents: input.agents ?? null,
|
|
474
475
|
});
|
|
475
476
|
return { rotationOrder: preparationResult.rotationOrder };
|
|
476
477
|
}
|
|
@@ -25,9 +25,8 @@ import {
|
|
|
25
25
|
ConsoleTabName,
|
|
26
26
|
} from './console/GenerateConsoleListsUseCase';
|
|
27
27
|
import { Issue } from '../entities/Issue';
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import { AGENT_FIELD_NAME } from '../entities/RequiredProjectField';
|
|
28
|
+
import { Project } from '../entities/Project';
|
|
29
|
+
import { ensureAgentOptionAndGetId } from './ensureAgentOptionAndGetId';
|
|
31
30
|
|
|
32
31
|
export class IssueNotFoundError extends Error {
|
|
33
32
|
constructor(issueUrl: string) {
|
|
@@ -566,41 +565,8 @@ export class NotifyFinishedIssuePreparationUseCase {
|
|
|
566
565
|
private ensureAgentOptionAndGetId = async (
|
|
567
566
|
project: Project,
|
|
568
567
|
agentName: string,
|
|
569
|
-
): Promise<string | null> =>
|
|
570
|
-
|
|
571
|
-
if (!project.agent) {
|
|
572
|
-
await this.projectRepository.createField(project, {
|
|
573
|
-
name: AGENT_FIELD_NAME,
|
|
574
|
-
dataType: 'SINGLE_SELECT',
|
|
575
|
-
options: [{ name: agentName, color: 'GRAY' as const, description: '' }],
|
|
576
|
-
});
|
|
577
|
-
const refreshed = await this.projectRepository.getByUrl(project.url);
|
|
578
|
-
const created = refreshed.agent?.options.find(
|
|
579
|
-
(o) => normalizeProjectFieldName(o.name) === normalizedTarget,
|
|
580
|
-
);
|
|
581
|
-
return created?.id ?? null;
|
|
582
|
-
}
|
|
583
|
-
const existing = project.agent.options.find(
|
|
584
|
-
(o) => normalizeProjectFieldName(o.name) === normalizedTarget,
|
|
585
|
-
);
|
|
586
|
-
if (existing) {
|
|
587
|
-
return existing.id;
|
|
588
|
-
}
|
|
589
|
-
const mergedOptions: (Omit<FieldOption, 'id'> & {
|
|
590
|
-
id: FieldOption['id'] | null;
|
|
591
|
-
})[] = [
|
|
592
|
-
...project.agent.options.map((o) => ({ ...o })),
|
|
593
|
-
{ id: null, name: agentName, color: 'GRAY' as const, description: '' },
|
|
594
|
-
];
|
|
595
|
-
const updatedOptions = await this.projectRepository.updateAgentList(
|
|
596
|
-
project,
|
|
597
|
-
mergedOptions,
|
|
598
|
-
);
|
|
599
|
-
const added = updatedOptions.find(
|
|
600
|
-
(o) => normalizeProjectFieldName(o.name) === normalizedTarget,
|
|
601
|
-
);
|
|
602
|
-
return added?.id ?? null;
|
|
603
|
-
};
|
|
568
|
+
): Promise<string | null> =>
|
|
569
|
+
ensureAgentOptionAndGetId(this.projectRepository, project, agentName);
|
|
604
570
|
|
|
605
571
|
private patchConsoleTab = async (issue: Issue): Promise<void> => {
|
|
606
572
|
if (!this.consoleTabsRepository) return;
|
|
@@ -9,7 +9,7 @@ import { ClaudeTokenUsageRepository } from './adapter-interfaces/ClaudeTokenUsag
|
|
|
9
9
|
import { TakeOwnershipSpawnRepository } from './adapter-interfaces/TakeOwnershipSpawnRepository';
|
|
10
10
|
import { ClaudeTokenUsage } from '../entities/ClaudeTokenUsage';
|
|
11
11
|
import { Issue } from '../entities/Issue';
|
|
12
|
-
import { Project } from '../entities/Project';
|
|
12
|
+
import { FieldOption, Project } from '../entities/Project';
|
|
13
13
|
import { StoryObjectMap } from '../entities/StoryObjectMap';
|
|
14
14
|
type Mocked<T> = jest.Mocked<T> & jest.MockedObject<T>;
|
|
15
15
|
|
|
@@ -82,7 +82,9 @@ const createMockProject = (): Project => ({
|
|
|
82
82
|
|
|
83
83
|
describe('StartPreparationUseCase', () => {
|
|
84
84
|
let useCase: StartPreparationUseCase;
|
|
85
|
-
let mockProjectRepository: Mocked<
|
|
85
|
+
let mockProjectRepository: Mocked<
|
|
86
|
+
Pick<ProjectRepository, 'getByUrl' | 'createField' | 'updateAgentList'>
|
|
87
|
+
>;
|
|
86
88
|
let mockIssueRepository: Mocked<
|
|
87
89
|
Pick<
|
|
88
90
|
IssueRepository,
|
|
@@ -94,6 +96,8 @@ describe('StartPreparationUseCase', () => {
|
|
|
94
96
|
| 'closePullRequest'
|
|
95
97
|
| 'deletePullRequestBranch'
|
|
96
98
|
| 'createCommentByUrl'
|
|
99
|
+
| 'setIssueAgentField'
|
|
100
|
+
| 'removeLabel'
|
|
97
101
|
>
|
|
98
102
|
>;
|
|
99
103
|
let mockLocalCommandRunner: Mocked<LocalCommandRunner>;
|
|
@@ -105,6 +109,8 @@ describe('StartPreparationUseCase', () => {
|
|
|
105
109
|
mockProject = createMockProject();
|
|
106
110
|
mockProjectRepository = {
|
|
107
111
|
getByUrl: jest.fn(),
|
|
112
|
+
createField: jest.fn().mockResolvedValue(undefined),
|
|
113
|
+
updateAgentList: jest.fn().mockResolvedValue([]),
|
|
108
114
|
};
|
|
109
115
|
mockIssueRepository = {
|
|
110
116
|
getStoryObjectMap: jest.fn().mockResolvedValue(new Map()),
|
|
@@ -115,6 +121,8 @@ describe('StartPreparationUseCase', () => {
|
|
|
115
121
|
closePullRequest: jest.fn().mockResolvedValue(undefined),
|
|
116
122
|
deletePullRequestBranch: jest.fn().mockResolvedValue(undefined),
|
|
117
123
|
createCommentByUrl: jest.fn().mockResolvedValue(undefined),
|
|
124
|
+
setIssueAgentField: jest.fn().mockResolvedValue(undefined),
|
|
125
|
+
removeLabel: jest.fn().mockResolvedValue(undefined),
|
|
118
126
|
};
|
|
119
127
|
mockLocalCommandRunner = {
|
|
120
128
|
runCommand: jest.fn(),
|
|
@@ -191,6 +199,181 @@ describe('StartPreparationUseCase', () => {
|
|
|
191
199
|
]);
|
|
192
200
|
});
|
|
193
201
|
|
|
202
|
+
describe('agent designation label migration to the Agent project field', () => {
|
|
203
|
+
const projectWithAgentField = (options: FieldOption[]): Project => ({
|
|
204
|
+
...createMockProject(),
|
|
205
|
+
agent: { name: 'Agent', fieldId: 'agent-field-id', options },
|
|
206
|
+
});
|
|
207
|
+
const runWithAgents = async (agents: string[] | null): Promise<void> => {
|
|
208
|
+
await useCase.run({
|
|
209
|
+
projectUrl: 'https://github.com/user/repo',
|
|
210
|
+
defaultAgentName: 'agent1',
|
|
211
|
+
defaultLlmModelName: 'claude-opus',
|
|
212
|
+
fallbackLlmModelName: null,
|
|
213
|
+
defaultLlmAgentName: null,
|
|
214
|
+
configFilePath: '/path/to/config.yml',
|
|
215
|
+
maximumPreparingIssuesCount: null,
|
|
216
|
+
utilizationPercentageThreshold: 90,
|
|
217
|
+
allowedIssueAuthors: ['testuser'],
|
|
218
|
+
manager: 'manager-user',
|
|
219
|
+
codexHomeCandidates: null,
|
|
220
|
+
labelsAsLlmAgentName: null,
|
|
221
|
+
agents,
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
const arrangeIssue = (project: Project, labels: string[]): void => {
|
|
225
|
+
mockProjectRepository.getByUrl.mockResolvedValue(project);
|
|
226
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
227
|
+
createMockStoryObjectMap([
|
|
228
|
+
createMockIssue({
|
|
229
|
+
url: 'url1',
|
|
230
|
+
title: 'Issue 1',
|
|
231
|
+
labels,
|
|
232
|
+
status: 'Awaiting Workspace',
|
|
233
|
+
}),
|
|
234
|
+
]),
|
|
235
|
+
);
|
|
236
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
237
|
+
stdout: '',
|
|
238
|
+
stderr: '',
|
|
239
|
+
exitCode: 0,
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
it('sets the existing Agent field option and removes the label when a label matches a configured agent definition', async () => {
|
|
244
|
+
const project = projectWithAgentField([
|
|
245
|
+
{
|
|
246
|
+
id: 'agent-option-impl',
|
|
247
|
+
name: 'impl',
|
|
248
|
+
color: 'GRAY',
|
|
249
|
+
description: '',
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
id: 'agent-option-chore',
|
|
253
|
+
name: 'chore',
|
|
254
|
+
color: 'GRAY',
|
|
255
|
+
description: '',
|
|
256
|
+
},
|
|
257
|
+
]);
|
|
258
|
+
arrangeIssue(project, ['chore']);
|
|
259
|
+
|
|
260
|
+
await runWithAgents(['impl', 'chore', 'accounting']);
|
|
261
|
+
|
|
262
|
+
expect(mockProjectRepository.updateAgentList.mock.calls).toHaveLength(0);
|
|
263
|
+
expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
|
|
264
|
+
['url1', project, 'agent-option-chore'],
|
|
265
|
+
]);
|
|
266
|
+
expect(mockIssueRepository.removeLabel.mock.calls).toHaveLength(1);
|
|
267
|
+
expect(mockIssueRepository.removeLabel.mock.calls[0][0]).toMatchObject({
|
|
268
|
+
url: 'url1',
|
|
269
|
+
});
|
|
270
|
+
expect(mockIssueRepository.removeLabel.mock.calls[0][1]).toBe('chore');
|
|
271
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][1]).toBe(
|
|
272
|
+
'chore',
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('creates the missing Agent field option before setting it on the issue', async () => {
|
|
277
|
+
const project = projectWithAgentField([]);
|
|
278
|
+
arrangeIssue(project, ['impl']);
|
|
279
|
+
mockProjectRepository.updateAgentList.mockResolvedValue([
|
|
280
|
+
{
|
|
281
|
+
id: 'agent-option-impl',
|
|
282
|
+
name: 'impl',
|
|
283
|
+
color: 'GRAY',
|
|
284
|
+
description: '',
|
|
285
|
+
},
|
|
286
|
+
]);
|
|
287
|
+
|
|
288
|
+
await runWithAgents(['impl']);
|
|
289
|
+
|
|
290
|
+
expect(mockProjectRepository.updateAgentList.mock.calls).toHaveLength(1);
|
|
291
|
+
expect(mockProjectRepository.updateAgentList.mock.calls[0][1]).toEqual([
|
|
292
|
+
{ id: null, name: 'impl', color: 'GRAY', description: '' },
|
|
293
|
+
]);
|
|
294
|
+
expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
|
|
295
|
+
['url1', project, 'agent-option-impl'],
|
|
296
|
+
]);
|
|
297
|
+
expect(mockIssueRepository.removeLabel.mock.calls).toHaveLength(1);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('creates the Agent field when the project has none, then sets it and removes the label', async () => {
|
|
301
|
+
const project = createMockProject();
|
|
302
|
+
arrangeIssue(project, ['chore']);
|
|
303
|
+
mockProjectRepository.getByUrl.mockResolvedValueOnce(project);
|
|
304
|
+
mockProjectRepository.getByUrl.mockResolvedValueOnce(
|
|
305
|
+
projectWithAgentField([
|
|
306
|
+
{
|
|
307
|
+
id: 'agent-option-chore',
|
|
308
|
+
name: 'chore',
|
|
309
|
+
color: 'GRAY',
|
|
310
|
+
description: '',
|
|
311
|
+
},
|
|
312
|
+
]),
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
await runWithAgents(['chore']);
|
|
316
|
+
|
|
317
|
+
expect(mockProjectRepository.createField.mock.calls).toHaveLength(1);
|
|
318
|
+
expect(mockProjectRepository.createField.mock.calls[0][1]).toEqual({
|
|
319
|
+
name: 'Agent',
|
|
320
|
+
dataType: 'SINGLE_SELECT',
|
|
321
|
+
options: [{ name: 'chore', color: 'GRAY', description: '' }],
|
|
322
|
+
});
|
|
323
|
+
expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
|
|
324
|
+
['url1', project, 'agent-option-chore'],
|
|
325
|
+
]);
|
|
326
|
+
expect(mockIssueRepository.removeLabel.mock.calls).toHaveLength(1);
|
|
327
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][1]).toBe(
|
|
328
|
+
'chore',
|
|
329
|
+
);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it('keeps the label and still uses it as the agent when the Agent field option cannot be resolved', async () => {
|
|
333
|
+
const project = createMockProject();
|
|
334
|
+
arrangeIssue(project, ['chore']);
|
|
335
|
+
mockProjectRepository.getByUrl.mockResolvedValue(project);
|
|
336
|
+
|
|
337
|
+
await runWithAgents(['chore']);
|
|
338
|
+
|
|
339
|
+
expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
|
|
340
|
+
expect(mockIssueRepository.removeLabel.mock.calls).toHaveLength(0);
|
|
341
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][1]).toBe(
|
|
342
|
+
'chore',
|
|
343
|
+
);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it('leaves the labels untouched when no label matches a configured agent definition', async () => {
|
|
347
|
+
const project = projectWithAgentField([
|
|
348
|
+
{
|
|
349
|
+
id: 'agent-option-impl',
|
|
350
|
+
name: 'impl',
|
|
351
|
+
color: 'GRAY',
|
|
352
|
+
description: '',
|
|
353
|
+
},
|
|
354
|
+
]);
|
|
355
|
+
arrangeIssue(project, ['category:triager']);
|
|
356
|
+
|
|
357
|
+
await runWithAgents(['impl']);
|
|
358
|
+
|
|
359
|
+
expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
|
|
360
|
+
expect(mockIssueRepository.removeLabel.mock.calls).toHaveLength(0);
|
|
361
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][1]).toBe(
|
|
362
|
+
'triager',
|
|
363
|
+
);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it('leaves the labels untouched when no agent definition is configured', async () => {
|
|
367
|
+
const project = projectWithAgentField([]);
|
|
368
|
+
arrangeIssue(project, ['chore']);
|
|
369
|
+
|
|
370
|
+
await runWithAgents(null);
|
|
371
|
+
|
|
372
|
+
expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
|
|
373
|
+
expect(mockIssueRepository.removeLabel.mock.calls).toHaveLength(0);
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
194
377
|
it('keeps an issue out of Preparation when the aw command exits non-zero', async () => {
|
|
195
378
|
const awaitingIssues: Issue[] = [
|
|
196
379
|
createMockIssue({
|
|
@@ -6349,9 +6532,11 @@ describe('StartPreparationUseCase', () => {
|
|
|
6349
6532
|
|
|
6350
6533
|
describe('StartPreparationUseCase.buildRotationOrder', () => {
|
|
6351
6534
|
const mockProjectRepositoryForRotation: Mocked<
|
|
6352
|
-
Pick<ProjectRepository, 'getByUrl'>
|
|
6535
|
+
Pick<ProjectRepository, 'getByUrl' | 'createField' | 'updateAgentList'>
|
|
6353
6536
|
> = {
|
|
6354
6537
|
getByUrl: jest.fn(),
|
|
6538
|
+
createField: jest.fn(),
|
|
6539
|
+
updateAgentList: jest.fn(),
|
|
6355
6540
|
};
|
|
6356
6541
|
const mockIssueRepositoryForRotation: Mocked<
|
|
6357
6542
|
Pick<
|
|
@@ -6364,6 +6549,8 @@ describe('StartPreparationUseCase.buildRotationOrder', () => {
|
|
|
6364
6549
|
| 'closePullRequest'
|
|
6365
6550
|
| 'deletePullRequestBranch'
|
|
6366
6551
|
| 'createCommentByUrl'
|
|
6552
|
+
| 'setIssueAgentField'
|
|
6553
|
+
| 'removeLabel'
|
|
6367
6554
|
>
|
|
6368
6555
|
> = {
|
|
6369
6556
|
getStoryObjectMap: jest.fn(),
|
|
@@ -6374,6 +6561,8 @@ describe('StartPreparationUseCase.buildRotationOrder', () => {
|
|
|
6374
6561
|
closePullRequest: jest.fn(),
|
|
6375
6562
|
deletePullRequestBranch: jest.fn(),
|
|
6376
6563
|
createCommentByUrl: jest.fn(),
|
|
6564
|
+
setIssueAgentField: jest.fn(),
|
|
6565
|
+
removeLabel: jest.fn(),
|
|
6377
6566
|
};
|
|
6378
6567
|
const mockLocalCommandRunnerForRotation: Mocked<LocalCommandRunner> = {
|
|
6379
6568
|
runCommand: jest.fn(),
|
|
@@ -6666,7 +6855,11 @@ describe('StartPreparationUseCase.getTokenConcurrentLimit', () => {
|
|
|
6666
6855
|
let useCase: StartPreparationUseCase;
|
|
6667
6856
|
beforeEach(() => {
|
|
6668
6857
|
useCase = new StartPreparationUseCase(
|
|
6669
|
-
{
|
|
6858
|
+
{
|
|
6859
|
+
getByUrl: jest.fn(),
|
|
6860
|
+
createField: jest.fn(),
|
|
6861
|
+
updateAgentList: jest.fn(),
|
|
6862
|
+
},
|
|
6670
6863
|
{
|
|
6671
6864
|
getStoryObjectMap: jest.fn(),
|
|
6672
6865
|
getAllOpened: jest.fn(),
|
|
@@ -6676,6 +6869,8 @@ describe('StartPreparationUseCase.getTokenConcurrentLimit', () => {
|
|
|
6676
6869
|
closePullRequest: jest.fn(),
|
|
6677
6870
|
deletePullRequestBranch: jest.fn(),
|
|
6678
6871
|
createCommentByUrl: jest.fn(),
|
|
6872
|
+
setIssueAgentField: jest.fn(),
|
|
6873
|
+
removeLabel: jest.fn(),
|
|
6679
6874
|
},
|
|
6680
6875
|
{ runCommand: jest.fn() },
|
|
6681
6876
|
{
|
|
@@ -9,6 +9,9 @@ import {
|
|
|
9
9
|
AWAITING_WORKSPACE_STATUS_NAME,
|
|
10
10
|
PREPARATION_STATUS_NAME,
|
|
11
11
|
} from '../entities/WorkflowStatus';
|
|
12
|
+
import { ensureAgentOptionAndGetId } from './ensureAgentOptionAndGetId';
|
|
13
|
+
import { Issue } from '../entities/Issue';
|
|
14
|
+
import { Project } from '../entities/Project';
|
|
12
15
|
|
|
13
16
|
const NORMAL_CONCURRENT_LIMIT = 6;
|
|
14
17
|
const SEVEN_DAY_THROTTLE_START_THRESHOLD = 0.8;
|
|
@@ -32,7 +35,10 @@ export type RotationOrderEntry = {
|
|
|
32
35
|
|
|
33
36
|
export class StartPreparationUseCase {
|
|
34
37
|
constructor(
|
|
35
|
-
private readonly projectRepository: Pick<
|
|
38
|
+
private readonly projectRepository: Pick<
|
|
39
|
+
ProjectRepository,
|
|
40
|
+
'getByUrl' | 'createField' | 'updateAgentList'
|
|
41
|
+
>,
|
|
36
42
|
private readonly issueRepository: Pick<
|
|
37
43
|
IssueRepository,
|
|
38
44
|
| 'getStoryObjectMap'
|
|
@@ -43,6 +49,8 @@ export class StartPreparationUseCase {
|
|
|
43
49
|
| 'closePullRequest'
|
|
44
50
|
| 'deletePullRequestBranch'
|
|
45
51
|
| 'createCommentByUrl'
|
|
52
|
+
| 'setIssueAgentField'
|
|
53
|
+
| 'removeLabel'
|
|
46
54
|
>,
|
|
47
55
|
private readonly localCommandRunner: LocalCommandRunner,
|
|
48
56
|
private readonly claudeTokenUsageRepository: ClaudeTokenUsageRepository,
|
|
@@ -302,6 +310,41 @@ export class StartPreparationUseCase {
|
|
|
302
310
|
return [...selectedEntries, ...excluded];
|
|
303
311
|
};
|
|
304
312
|
|
|
313
|
+
private migrateAgentDesignationLabelToProjectField = async (
|
|
314
|
+
issue: Issue,
|
|
315
|
+
project: Project,
|
|
316
|
+
configuredAgentNames: string[] | null,
|
|
317
|
+
): Promise<void> => {
|
|
318
|
+
const agentLabel =
|
|
319
|
+
configuredAgentNames === null
|
|
320
|
+
? undefined
|
|
321
|
+
: issue.labels.find((label: string) =>
|
|
322
|
+
configuredAgentNames.includes(label),
|
|
323
|
+
);
|
|
324
|
+
if (agentLabel === undefined) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
issue.agent = agentLabel;
|
|
328
|
+
const agentOptionId = await ensureAgentOptionAndGetId(
|
|
329
|
+
this.projectRepository,
|
|
330
|
+
project,
|
|
331
|
+
agentLabel,
|
|
332
|
+
);
|
|
333
|
+
if (agentOptionId === null) {
|
|
334
|
+
console.warn(
|
|
335
|
+
`Agent field option '${agentLabel}' could not be resolved for ${issue.url}. Keeping the label as the agent designation.`,
|
|
336
|
+
);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
await this.issueRepository.setIssueAgentField(
|
|
340
|
+
issue.url,
|
|
341
|
+
project,
|
|
342
|
+
agentOptionId,
|
|
343
|
+
);
|
|
344
|
+
await this.issueRepository.removeLabel(issue, agentLabel);
|
|
345
|
+
issue.labels = issue.labels.filter((label) => label !== agentLabel);
|
|
346
|
+
};
|
|
347
|
+
|
|
305
348
|
run = async (params: {
|
|
306
349
|
projectUrl: string;
|
|
307
350
|
defaultAgentName: string;
|
|
@@ -315,6 +358,7 @@ export class StartPreparationUseCase {
|
|
|
315
358
|
manager: string;
|
|
316
359
|
codexHomeCandidates: string[] | null;
|
|
317
360
|
labelsAsLlmAgentName: string[] | null;
|
|
361
|
+
agents?: string[] | null;
|
|
318
362
|
}): Promise<{ rotationOrder: RotationOrderEntry[] | null }> => {
|
|
319
363
|
const tokenUsages =
|
|
320
364
|
await this.claudeTokenUsageRepository.getAvailableTokenUsages();
|
|
@@ -476,6 +520,11 @@ export class StartPreparationUseCase {
|
|
|
476
520
|
exclusionCounts.notAssignedToManager++;
|
|
477
521
|
continue;
|
|
478
522
|
}
|
|
523
|
+
await this.migrateAgentDesignationLabelToProjectField(
|
|
524
|
+
issue,
|
|
525
|
+
project,
|
|
526
|
+
params.agents ?? null,
|
|
527
|
+
);
|
|
479
528
|
const mappedAgentFromLabel =
|
|
480
529
|
params.labelsAsLlmAgentName !== null
|
|
481
530
|
? issue.labels.find((label: string) =>
|
|
@@ -616,6 +616,19 @@ describe('GenerateConsoleListsUseCase', () => {
|
|
|
616
616
|
'second',
|
|
617
617
|
]);
|
|
618
618
|
});
|
|
619
|
+
|
|
620
|
+
it('groups items of different unknown stories contiguously even when interleaved by original position', () => {
|
|
621
|
+
const result = run([
|
|
622
|
+
makeIssue({ status: 'Unread', story: 'Unknown Story A' }),
|
|
623
|
+
makeIssue({ status: 'Unread', story: 'Unknown Story B' }),
|
|
624
|
+
makeIssue({ status: 'Unread', story: 'Unknown Story A' }),
|
|
625
|
+
]);
|
|
626
|
+
expect(result.unread.items.map((i) => i.story)).toEqual([
|
|
627
|
+
'Unknown Story A',
|
|
628
|
+
'Unknown Story A',
|
|
629
|
+
'Unknown Story B',
|
|
630
|
+
]);
|
|
631
|
+
});
|
|
619
632
|
});
|
|
620
633
|
|
|
621
634
|
describe('options construction', () => {
|
|
@@ -364,7 +364,12 @@ export class GenerateConsoleListsUseCase {
|
|
|
364
364
|
position,
|
|
365
365
|
sortKey: indexByStory.get(item.story) ?? UNKNOWN_STORY_SORT_INDEX,
|
|
366
366
|
}))
|
|
367
|
-
.sort((a, b) =>
|
|
367
|
+
.sort((a, b) => {
|
|
368
|
+
if (a.sortKey !== b.sortKey) return a.sortKey - b.sortKey;
|
|
369
|
+
if (a.item.story !== b.item.story)
|
|
370
|
+
return a.item.story.localeCompare(b.item.story);
|
|
371
|
+
return a.position - b.position;
|
|
372
|
+
})
|
|
368
373
|
.map((entry) => entry.item);
|
|
369
374
|
};
|
|
370
375
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { FieldOption, Project } from '../entities/Project';
|
|
2
|
+
import { normalizeProjectFieldName } from '../entities/ProjectFieldName';
|
|
3
|
+
import { AGENT_FIELD_NAME } from '../entities/RequiredProjectField';
|
|
4
|
+
import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
|
|
5
|
+
|
|
6
|
+
export const ensureAgentOptionAndGetId = async (
|
|
7
|
+
projectRepository: Pick<
|
|
8
|
+
ProjectRepository,
|
|
9
|
+
'createField' | 'getByUrl' | 'updateAgentList'
|
|
10
|
+
>,
|
|
11
|
+
project: Project,
|
|
12
|
+
agentName: string,
|
|
13
|
+
): Promise<string | null> => {
|
|
14
|
+
const normalizedTarget = normalizeProjectFieldName(agentName);
|
|
15
|
+
if (!project.agent) {
|
|
16
|
+
await projectRepository.createField(project, {
|
|
17
|
+
name: AGENT_FIELD_NAME,
|
|
18
|
+
dataType: 'SINGLE_SELECT',
|
|
19
|
+
options: [{ name: agentName, color: 'GRAY' as const, description: '' }],
|
|
20
|
+
});
|
|
21
|
+
const refreshed = await projectRepository.getByUrl(project.url);
|
|
22
|
+
const created = refreshed.agent?.options.find(
|
|
23
|
+
(option) => normalizeProjectFieldName(option.name) === normalizedTarget,
|
|
24
|
+
);
|
|
25
|
+
return created?.id ?? null;
|
|
26
|
+
}
|
|
27
|
+
const existing = project.agent.options.find(
|
|
28
|
+
(option) => normalizeProjectFieldName(option.name) === normalizedTarget,
|
|
29
|
+
);
|
|
30
|
+
if (existing) {
|
|
31
|
+
return existing.id;
|
|
32
|
+
}
|
|
33
|
+
const mergedOptions: (Omit<FieldOption, 'id'> & {
|
|
34
|
+
id: FieldOption['id'] | null;
|
|
35
|
+
})[] = [
|
|
36
|
+
...project.agent.options.map((option) => ({ ...option })),
|
|
37
|
+
{ id: null, name: agentName, color: 'GRAY' as const, description: '' },
|
|
38
|
+
];
|
|
39
|
+
const updatedOptions = await projectRepository.updateAgentList(
|
|
40
|
+
project,
|
|
41
|
+
mergedOptions,
|
|
42
|
+
);
|
|
43
|
+
const created = updatedOptions.find(
|
|
44
|
+
(option) => normalizeProjectFieldName(option.name) === normalizedTarget,
|
|
45
|
+
);
|
|
46
|
+
return created?.id ?? null;
|
|
47
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AA8LzB,eAAO,MAAM,OAAO,SAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AA8LzB,eAAO,MAAM,OAAO,SAAgB,CAAC;AA8gCrC,eAAO,MAAM,uBAAuB,GAAI,OAAO,OAAO,KAAG,IAGxD,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EAAE,EACd,kBAAkB,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KACzC,OAAO,CAAC,IAAI,CAMd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HandleScheduledEventUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/HandleScheduledEventUseCase.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"HandleScheduledEventUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/HandleScheduledEventUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AA0BnF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,QAAQ,EAAE,MAAM;CAI7B;AACD,qBAAa,uBAAwB,SAAQ,KAAK;gBAE9C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,cAAc,EAAE,MAAM,GAAG,IAAI;CAOhC;AAID,qBAAa,qCAAqC;IAK9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAgBhC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAIvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAhCzC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA0B;IAClE,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAkC;gBAG/D,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,UAAU,GAAG,iBAAiB,GAAG,aAAa,CAC/C,EACgB,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,KAAK,GACL,QAAQ,GACR,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,oBAAoB,GACpB,mBAAmB,GACnB,oBAAoB,GACpB,gCAAgC,GAChC,oBAAoB,GACpB,iCAAiC,GACjC,qBAAqB,GACrB,oBAAoB,CACvB,EACgB,sBAAsB,EAAE,IAAI,CAC3C,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC,EACgB,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,gBAAgB,CACjB,EACgB,qBAAqB,CAAC,GAAE,qBAAqB,GAAG,IAAI,aAAA;IAQvE,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,iCAAiC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjD,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACtC,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACvC,6BAA6B,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAChD,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QACxD,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KAC1B,KAAG,OAAO,CAAC,IAAI,CAAC,CAkRf;IAEF,OAAO,CAAC,eAAe,CAIgD;IAEvE,OAAO,CAAC,iBAAiB,CAkDvB;IAEF,OAAO,CAAC,qBAAqB,CAuB3B;IAEF,OAAO,CAAC,gCAAgC,CAoBtC;IAEF,OAAO,CAAC,uBAAuB,CAQ7B;IAEF,OAAO,CAAC,+BAA+B,CAgCrC;IAEF,OAAO,CAAC,uBAAuB,CAO7B;IAEF,OAAO,CAAC,oBAAoB,CA0B1B;IAEF,OAAO,CAAC,yBAAyB,CAIuC;IAExE,OAAO,CAAC,eAAe,CAmCrB;CACH"}
|
|
@@ -20,7 +20,7 @@ export declare class StartPreparationUseCase {
|
|
|
20
20
|
private readonly localCommandRunner;
|
|
21
21
|
private readonly claudeTokenUsageRepository;
|
|
22
22
|
private readonly takeOwnershipSpawnRepository;
|
|
23
|
-
constructor(projectRepository: Pick<ProjectRepository, 'getByUrl'>, issueRepository: Pick<IssueRepository, 'getStoryObjectMap' | 'getAllOpened' | 'updateStatus' | 'findRelatedOpenPRs' | 'getOpenPullRequest' | 'closePullRequest' | 'deletePullRequestBranch' | 'createCommentByUrl'>, localCommandRunner: LocalCommandRunner, claudeTokenUsageRepository: ClaudeTokenUsageRepository, takeOwnershipSpawnRepository: TakeOwnershipSpawnRepository);
|
|
23
|
+
constructor(projectRepository: Pick<ProjectRepository, 'getByUrl' | 'createField' | 'updateAgentList'>, issueRepository: Pick<IssueRepository, 'getStoryObjectMap' | 'getAllOpened' | 'updateStatus' | 'findRelatedOpenPRs' | 'getOpenPullRequest' | 'closePullRequest' | 'deletePullRequestBranch' | 'createCommentByUrl' | 'setIssueAgentField' | 'removeLabel'>, localCommandRunner: LocalCommandRunner, claudeTokenUsageRepository: ClaudeTokenUsageRepository, takeOwnershipSpawnRepository: TakeOwnershipSpawnRepository);
|
|
24
24
|
private weeklyLimitTypeForModel;
|
|
25
25
|
private isWithinCooldown;
|
|
26
26
|
private isModelWeeklyLimitRejected;
|
|
@@ -31,6 +31,7 @@ export declare class StartPreparationUseCase {
|
|
|
31
31
|
getTokenConcurrentLimit: (fiveHourUtilization: number, sevenDayUtilization: number, selectionWeight?: number) => number;
|
|
32
32
|
private selectRotationTokens;
|
|
33
33
|
buildRotationOrder: (tokenUsages: ClaudeTokenUsage[], utilizationPercentageThreshold: number, modelName: string | null) => RotationOrderEntry[];
|
|
34
|
+
private migrateAgentDesignationLabelToProjectField;
|
|
34
35
|
run: (params: {
|
|
35
36
|
projectUrl: string;
|
|
36
37
|
defaultAgentName: string;
|
|
@@ -44,6 +45,7 @@ export declare class StartPreparationUseCase {
|
|
|
44
45
|
manager: string;
|
|
45
46
|
codexHomeCandidates: string[] | null;
|
|
46
47
|
labelsAsLlmAgentName: string[] | null;
|
|
48
|
+
agents?: string[] | null;
|
|
47
49
|
}) => Promise<{
|
|
48
50
|
rotationOrder: RotationOrderEntry[] | null;
|
|
49
51
|
}>;
|