github-issue-tower-defence-management 1.170.1 → 1.172.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 (51) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/adapter/entry-points/console/ui-dist/assets/index-Bh2slMtk.css +2 -0
  3. package/bin/adapter/entry-points/console/ui-dist/assets/{index-Db4JRB24.js → index-ZYMkO0fm.js} +2 -2
  4. package/bin/adapter/entry-points/console/ui-dist/index.html +2 -2
  5. package/bin/domain/usecases/ClearPastNextActionDateHourUseCase.js +2 -1
  6. package/bin/domain/usecases/ClearPastNextActionDateHourUseCase.js.map +1 -1
  7. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +4 -6
  8. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  9. package/bin/domain/usecases/StartPreparationUseCase.js +10 -10
  10. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  11. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js +1 -0
  12. package/bin/domain/usecases/console/GenerateConsoleListsUseCase.js.map +1 -1
  13. package/bin/domain/usecases/issueReactivationTriggerIsPending.js +14 -0
  14. package/bin/domain/usecases/issueReactivationTriggerIsPending.js.map +1 -0
  15. package/package.json +1 -1
  16. package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +26 -0
  17. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +13 -7
  18. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.stories.tsx +32 -0
  19. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.test.tsx +29 -0
  20. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.tsx +3 -0
  21. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemSummary.stories.tsx +4 -0
  22. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemSummary.test.tsx +49 -0
  23. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemSummary.tsx +7 -0
  24. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.test.ts +1 -0
  25. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.test.ts +1 -0
  26. package/src/adapter/entry-points/console/ui/src/features/console/logic/grouping.test.ts +1 -0
  27. package/src/adapter/entry-points/console/ui/src/features/console/logic/overlay.test.ts +1 -0
  28. package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +1 -0
  29. package/src/adapter/entry-points/console/ui/src/features/console/testing/fixtures.ts +25 -0
  30. package/src/adapter/entry-points/console/ui/src/index.css +10 -0
  31. package/src/adapter/entry-points/console/ui-dist/assets/index-Bh2slMtk.css +2 -0
  32. package/src/adapter/entry-points/console/ui-dist/assets/{index-Db4JRB24.js → index-ZYMkO0fm.js} +2 -2
  33. package/src/adapter/entry-points/console/ui-dist/index.html +2 -2
  34. package/src/adapter/entry-points/handlers/FileSystemConsoleTabsRepository.test.ts +1 -0
  35. package/src/domain/usecases/ClearPastNextActionDateHourUseCase.ts +2 -5
  36. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +1 -1
  37. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +4 -12
  38. package/src/domain/usecases/StartPreparationUseCase.ts +15 -20
  39. package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +20 -0
  40. package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +2 -0
  41. package/src/domain/usecases/issueReactivationTriggerIsPending.test.ts +530 -0
  42. package/src/domain/usecases/issueReactivationTriggerIsPending.ts +23 -0
  43. package/types/domain/usecases/ClearPastNextActionDateHourUseCase.d.ts.map +1 -1
  44. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  45. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
  46. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts +1 -0
  47. package/types/domain/usecases/console/GenerateConsoleListsUseCase.d.ts.map +1 -1
  48. package/types/domain/usecases/issueReactivationTriggerIsPending.d.ts +4 -0
  49. package/types/domain/usecases/issueReactivationTriggerIsPending.d.ts.map +1 -0
  50. package/bin/adapter/entry-points/console/ui-dist/assets/index-U8I8ESZj.css +0 -2
  51. package/src/adapter/entry-points/console/ui-dist/assets/index-U8I8ESZj.css +0 -2
@@ -4,8 +4,8 @@
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-Db4JRB24.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-U8I8ESZj.css">
7
+ <script type="module" crossorigin src="/assets/index-ZYMkO0fm.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-Bh2slMtk.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -18,6 +18,7 @@ const makeItem = (
18
18
  isPr: false,
19
19
  story: 'Story A',
20
20
  status: 'Awaiting Quality Check',
21
+ agent: null,
21
22
  nextActionDate: null,
22
23
  nextActionHour: null,
23
24
  dependedIssueUrls: [],
@@ -1,6 +1,7 @@
1
1
  import { Issue } from '../entities/Issue';
2
2
  import { IssueRepository } from './adapter-interfaces/IssueRepository';
3
3
  import { Project } from '../entities/Project';
4
+ import { issueReactivationTriggerStartOfTomorrow } from './issueReactivationTriggerIsPending';
4
5
 
5
6
  export class ClearPastNextActionDateHourUseCase {
6
7
  constructor(
@@ -57,11 +58,7 @@ export class ClearPastNextActionDateHourUseCase {
57
58
  if (!nextActionDate) {
58
59
  return;
59
60
  }
60
- const startOfTomorrow = new Date(
61
- now.getFullYear(),
62
- now.getMonth(),
63
- now.getDate() + 1,
64
- );
61
+ const startOfTomorrow = issueReactivationTriggerStartOfTomorrow(now);
65
62
  for (const issue of input.issues) {
66
63
  if (
67
64
  issue.nextActionHour !== null ||
@@ -518,7 +518,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
518
518
  );
519
519
  expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
520
520
  expect.objectContaining({ url: 'https://github.com/user/repo/issues/1' }),
521
- expect.stringContaining('Issue has next action date or hour set:'),
521
+ expect.stringContaining('Reactivation trigger not yet reached:'),
522
522
  );
523
523
  });
524
524
 
@@ -27,6 +27,7 @@ import {
27
27
  import { Issue } from '../entities/Issue';
28
28
  import { Project } from '../entities/Project';
29
29
  import { ensureAgentOptionAndGetId } from './ensureAgentOptionAndGetId';
30
+ import { issueReactivationTriggerIsPending } from './issueReactivationTriggerIsPending';
30
31
 
31
32
  export class IssueNotFoundError extends Error {
32
33
  constructor(issueUrl: string) {
@@ -198,17 +199,7 @@ export class NotifyFinishedIssuePreparationUseCase {
198
199
  }
199
200
 
200
201
  const evaluatedAt = new Date();
201
- const startOfTomorrow = new Date(
202
- evaluatedAt.getFullYear(),
203
- evaluatedAt.getMonth(),
204
- evaluatedAt.getDate() + 1,
205
- );
206
- const hasFutureNextActionDate =
207
- issue.nextActionDate !== null && issue.nextActionDate >= startOfTomorrow;
208
- const hasUnreachedNextActionHour =
209
- issue.nextActionHour !== null &&
210
- evaluatedAt.getHours() < issue.nextActionHour;
211
- if (hasFutureNextActionDate || hasUnreachedNextActionHour) {
202
+ if (issueReactivationTriggerIsPending(issue, evaluatedAt)) {
212
203
  issue.status = AWAITING_WORKSPACE_STATUS_NAME;
213
204
  await this.issueRepository.update(issue, project);
214
205
  await this.issueRepository.updateStatus(
@@ -219,7 +210,7 @@ export class NotifyFinishedIssuePreparationUseCase {
219
210
  await this.patchConsoleTab(issue);
220
211
  await this.issueCommentRepository.createComment(
221
212
  issue,
222
- `Issue has next action date or hour set: nextActionDate=${issue.nextActionDate?.toISOString() ?? 'null'}, nextActionHour=${issue.nextActionHour ?? 'null'}`,
213
+ `Reactivation trigger not yet reached: nextActionDate=${issue.nextActionDate?.toISOString() ?? 'null'}, nextActionHour=${issue.nextActionHour ?? 'null'}`,
223
214
  );
224
215
  return;
225
216
  }
@@ -675,6 +666,7 @@ export class NotifyFinishedIssuePreparationUseCase {
675
666
  isPr: issue.isPr,
676
667
  story: issue.story ?? '',
677
668
  status: issue.status,
669
+ agent: issue.agent,
678
670
  nextActionDate:
679
671
  issue.nextActionDate === null
680
672
  ? null
@@ -10,6 +10,7 @@ import {
10
10
  PREPARATION_STATUS_NAME,
11
11
  } from '../entities/WorkflowStatus';
12
12
  import { adoptIssueAgentDesignationLabel } from './AgentDesignationLabelAdoptUseCase';
13
+ import { issueReactivationTriggerIsPending } from './issueReactivationTriggerIsPending';
13
14
 
14
15
  const NORMAL_CONCURRENT_LIMIT = 6;
15
16
  const SEVEN_DAY_THROTTLE_START_THRESHOLD = 0.8;
@@ -433,17 +434,6 @@ export class StartPreparationUseCase {
433
434
  };
434
435
 
435
436
  const now = new Date();
436
- const currentHour = now.getHours();
437
- const todayStart = new Date(
438
- now.getFullYear(),
439
- now.getMonth(),
440
- now.getDate(),
441
- );
442
- const tomorrowStart = new Date(
443
- todayStart.getFullYear(),
444
- todayStart.getMonth(),
445
- todayStart.getDate() + 1,
446
- );
447
437
 
448
438
  for (
449
439
  let i = 0;
@@ -460,15 +450,20 @@ export class StartPreparationUseCase {
460
450
  console.warn(`Skipping ${issue.url}: worker already running.`);
461
451
  continue;
462
452
  }
463
- if (
464
- issue.nextActionDate !== null &&
465
- issue.nextActionDate >= tomorrowStart
466
- ) {
467
- exclusionCounts.futureNextActionDate++;
468
- continue;
469
- }
470
- if (issue.nextActionHour !== null && currentHour < issue.nextActionHour) {
471
- exclusionCounts.nextActionHourNotReached++;
453
+ if (issueReactivationTriggerIsPending(issue, now)) {
454
+ const startOfTomorrow = new Date(
455
+ now.getFullYear(),
456
+ now.getMonth(),
457
+ now.getDate() + 1,
458
+ );
459
+ if (
460
+ issue.nextActionDate !== null &&
461
+ issue.nextActionDate >= startOfTomorrow
462
+ ) {
463
+ exclusionCounts.futureNextActionDate++;
464
+ } else {
465
+ exclusionCounts.nextActionHourNotReached++;
466
+ }
472
467
  continue;
473
468
  }
474
469
  if (
@@ -508,6 +508,7 @@ describe('GenerateConsoleListsUseCase', () => {
508
508
  const item = result.unread.items[0];
509
509
  expect(Object.keys(item).sort()).toEqual(
510
510
  [
511
+ 'agent',
511
512
  'createdAt',
512
513
  'dependedIssueUrls',
513
514
  'isPr',
@@ -898,4 +899,23 @@ describe('GenerateConsoleListsUseCase', () => {
898
899
  expect(result.stories.stories).toEqual([]);
899
900
  });
900
901
  });
902
+
903
+ describe('agent field propagation', () => {
904
+ it('copies the agent value from the issue into the list item', () => {
905
+ const result = run([makeIssue({ status: 'Unread', agent: 'developer' })]);
906
+ expect(result.unread.items[0].agent).toBe('developer');
907
+ });
908
+
909
+ it('preserves null when the issue has no agent set', () => {
910
+ const result = run([makeIssue({ status: 'Unread', agent: null })]);
911
+ expect(result.unread.items[0].agent).toBeNull();
912
+ });
913
+
914
+ it('copies the agent into every tab that shows the issue', () => {
915
+ const result = run([
916
+ makeIssue({ status: 'Awaiting Quality Check', agent: 'chore' }),
917
+ ]);
918
+ expect(result.prs.items[0].agent).toBe('chore');
919
+ });
920
+ });
901
921
  });
@@ -20,6 +20,7 @@ export type ConsoleListItem = {
20
20
  isPr: boolean;
21
21
  story: string;
22
22
  status: string | null;
23
+ agent: string | null;
23
24
  nextActionDate: string | null;
24
25
  nextActionHour: number | null;
25
26
  dependedIssueUrls: string[];
@@ -308,6 +309,7 @@ export class GenerateConsoleListsUseCase {
308
309
  isPr: issue.isPr,
309
310
  story: issue.story ?? '',
310
311
  status: issue.status,
312
+ agent: issue.agent,
311
313
  nextActionDate:
312
314
  issue.nextActionDate === null ? null : issue.nextActionDate.toISOString(),
313
315
  nextActionHour: issue.nextActionHour,