github-issue-tower-defence-management 1.40.0 → 1.41.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 (52) hide show
  1. package/.github/workflows/umino-project.yml +5 -4
  2. package/CHANGELOG.md +13 -0
  3. package/README.md +21 -9
  4. package/bin/adapter/entry-points/cli/index.js +45 -10
  5. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  6. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +32 -8
  7. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  8. package/bin/adapter/repositories/NodeLocalCommandRunner.js +3 -3
  9. package/bin/adapter/repositories/NodeLocalCommandRunner.js.map +1 -1
  10. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +412 -177
  11. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
  12. package/bin/domain/usecases/HandleScheduledEventUseCase.js +5 -2
  13. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
  14. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +7 -2
  15. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
  16. package/bin/domain/usecases/StartPreparationUseCase.js +107 -72
  17. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/adapter/entry-points/cli/index.test.ts +26 -13
  20. package/src/adapter/entry-points/cli/index.ts +74 -13
  21. package/src/adapter/repositories/NodeLocalCommandRunner.test.ts +12 -12
  22. package/src/adapter/repositories/NodeLocalCommandRunner.ts +7 -4
  23. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +3 -0
  24. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +626 -265
  25. package/src/adapter/repositories/issue/RestIssueRepository.test.ts +3 -0
  26. package/src/domain/entities/Issue.ts +1 -0
  27. package/src/domain/usecases/GetStoryObjectMapUseCase.test.ts +1 -0
  28. package/src/domain/usecases/HandleScheduledEventUseCase.ts +11 -3
  29. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +1 -0
  30. package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +22 -9
  31. package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +8 -3
  32. package/src/domain/usecases/StartPreparationUseCase.test.ts +1696 -290
  33. package/src/domain/usecases/StartPreparationUseCase.ts +171 -126
  34. package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +2 -1
  35. package/src/domain/usecases/adapter-interfaces/LocalCommandRunner.ts +4 -1
  36. package/types/adapter/entry-points/cli/index.d.ts +4 -1
  37. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  38. package/types/adapter/repositories/NodeLocalCommandRunner.d.ts +1 -1
  39. package/types/adapter/repositories/NodeLocalCommandRunner.d.ts.map +1 -1
  40. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +5 -3
  41. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
  42. package/types/domain/entities/Issue.d.ts +1 -0
  43. package/types/domain/entities/Issue.d.ts.map +1 -1
  44. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +5 -1
  45. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
  46. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
  47. package/types/domain/usecases/StartPreparationUseCase.d.ts +10 -18
  48. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
  49. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +2 -1
  50. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -1
  51. package/types/domain/usecases/adapter-interfaces/LocalCommandRunner.d.ts +1 -1
  52. package/types/domain/usecases/adapter-interfaces/LocalCommandRunner.d.ts.map +1 -1
@@ -55,6 +55,7 @@ describe('RestIssueRepository', () => {
55
55
  isInProgress: false,
56
56
  isClosed: false,
57
57
  createdAt: new Date(),
58
+ author: '',
58
59
  };
59
60
 
60
61
  await restIssueRepository.updateLabels(issue, ['default']);
@@ -92,6 +93,7 @@ describe('RestIssueRepository', () => {
92
93
  isInProgress: false,
93
94
  isClosed: false,
94
95
  createdAt: new Date(),
96
+ author: '',
95
97
  };
96
98
 
97
99
  await restIssueRepository.updateLabels(issue, ['test', 'to-remove']);
@@ -130,6 +132,7 @@ describe('RestIssueRepository', () => {
130
132
  isInProgress: false,
131
133
  isClosed: false,
132
134
  createdAt: new Date(),
135
+ author: '',
133
136
  };
134
137
  await restIssueRepository.updateAssigneeList(issue, ['HiromiShikata']);
135
138
  const issueWithAssignee = await restIssueRepository.getIssue(issue.url);
@@ -23,4 +23,5 @@ export type Issue = {
23
23
  isInProgress: boolean;
24
24
  isClosed: boolean;
25
25
  createdAt: Date;
26
+ author: string;
26
27
  };
@@ -66,6 +66,7 @@ describe('GetStoryObjectMapUseCase', () => {
66
66
  isInProgress: false,
67
67
  isClosed: false,
68
68
  createdAt: new Date(),
69
+ author: '',
69
70
  ...overrides,
70
71
  });
71
72
 
@@ -73,8 +73,12 @@ export class HandleScheduledEventUseCase {
73
73
  awaitingWorkspaceStatus: string;
74
74
  preparationStatus: string;
75
75
  defaultAgentName: string;
76
- logFilePath?: string;
76
+ defaultLlmModelName?: string | null;
77
+ defaultLlmAgentName?: string | null;
78
+ configFilePath: string;
77
79
  maximumPreparingIssuesCount: number | null;
80
+ utilizationPercentageThreshold?: number;
81
+ allowedIssueAuthors?: string[] | null;
78
82
  preparationProcessCheckCommand?: string;
79
83
  } | null;
80
84
  notifyFinishedPreparation?: {
@@ -344,10 +348,14 @@ ${JSON.stringify(e)}
344
348
  awaitingWorkspaceStatus: input.startPreparation.awaitingWorkspaceStatus,
345
349
  preparationStatus: input.startPreparation.preparationStatus,
346
350
  defaultAgentName: input.startPreparation.defaultAgentName,
347
- logFilePath: input.startPreparation.logFilePath,
351
+ defaultLlmModelName: input.startPreparation.defaultLlmModelName ?? null,
352
+ defaultLlmAgentName: input.startPreparation.defaultLlmAgentName ?? null,
353
+ configFilePath: input.startPreparation.configFilePath,
348
354
  maximumPreparingIssuesCount:
349
355
  input.startPreparation.maximumPreparingIssuesCount,
350
- allowIssueCacheMinutes: input.allowIssueCacheMinutes,
356
+ utilizationPercentageThreshold:
357
+ input.startPreparation.utilizationPercentageThreshold ?? 90,
358
+ allowedIssueAuthors: input.startPreparation.allowedIssueAuthors ?? null,
351
359
  });
352
360
  }
353
361
  if (input.notifyFinishedPreparation) {
@@ -46,6 +46,7 @@ const createMockIssue = (overrides: Partial<Issue> = {}): Issue => ({
46
46
  isInProgress: false,
47
47
  isClosed: false,
48
48
  createdAt: new Date(),
49
+ author: '',
49
50
  ...overrides,
50
51
  });
51
52
 
@@ -30,6 +30,7 @@ const createMockIssue = (overrides: Partial<Issue> = {}): Issue => ({
30
30
  isInProgress: false,
31
31
  isClosed: false,
32
32
  createdAt: new Date(),
33
+ author: '',
33
34
  ...overrides,
34
35
  });
35
36
 
@@ -136,9 +137,13 @@ describe('RevertOrphanedPreparationUseCase', () => {
136
137
  expect(mockIssueRepository.createComment.mock.calls).toHaveLength(1);
137
138
  expect(mockIssueRepository.createComment.mock.calls[0][0]).toBe(stuckIssue);
138
139
  expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
139
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe(
140
- 'pgrep -fa "claude-agent.*https://github.com/user/repo/issues/10"',
141
- );
140
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe('sh');
141
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
142
+ '-c',
143
+ 'pgrep -fa "claude-agent.*$1"',
144
+ '--',
145
+ 'https://github.com/user/repo/issues/10',
146
+ ]);
142
147
  });
143
148
 
144
149
  it('should leave in-flight Preparation issue untouched when check command exits zero', async () => {
@@ -196,9 +201,13 @@ describe('RevertOrphanedPreparationUseCase', () => {
196
201
  });
197
202
 
198
203
  expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
199
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe(
200
- 'check https://github.com/user/repo/issues/10',
201
- );
204
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe('sh');
205
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
206
+ '-c',
207
+ 'check $1',
208
+ '--',
209
+ 'https://github.com/user/repo/issues/10',
210
+ ]);
202
211
  expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
203
212
  });
204
213
 
@@ -295,8 +304,12 @@ describe('RevertOrphanedPreparationUseCase', () => {
295
304
  });
296
305
 
297
306
  expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
298
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe(
299
- 'pgrep -fa "claude-agent.*https://github.com/org/project/issues/99"',
300
- );
307
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe('sh');
308
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
309
+ '-c',
310
+ 'pgrep -fa "claude-agent.*$1"',
311
+ '--',
312
+ 'https://github.com/org/project/issues/99',
313
+ ]);
301
314
  });
302
315
  });
@@ -51,11 +51,16 @@ export class RevertOrphanedPreparationUseCase {
51
51
  }
52
52
 
53
53
  for (const issue of preparationIssues) {
54
- const command = params.preparationProcessCheckCommand.replace(
54
+ const commandTemplate = params.preparationProcessCheckCommand.replace(
55
55
  '{URL}',
56
- issue.url,
56
+ '$1',
57
57
  );
58
- const { exitCode } = await this.localCommandRunner.runCommand(command);
58
+ const { exitCode } = await this.localCommandRunner.runCommand('sh', [
59
+ '-c',
60
+ commandTemplate,
61
+ '--',
62
+ issue.url,
63
+ ]);
59
64
  if (exitCode !== 0) {
60
65
  await this.issueRepository.updateStatus(
61
66
  project,