github-issue-tower-defence-management 1.59.0 → 1.60.1

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 (46) hide show
  1. package/.github/workflows/create-pr.yml +1 -1
  2. package/.github/workflows/test.yml +4 -0
  3. package/.github/workflows/umino-project.yml +3 -3
  4. package/CHANGELOG.md +14 -0
  5. package/bin/adapter/proxy/ClaudeMessageResponseParser.js +123 -0
  6. package/bin/adapter/proxy/ClaudeMessageResponseParser.js.map +1 -0
  7. package/bin/adapter/proxy/proxyEntry.js +16 -3
  8. package/bin/adapter/proxy/proxyEntry.js.map +1 -1
  9. package/bin/adapter/repositories/SqliteClaudeMessageResponseRepository.js +186 -0
  10. package/bin/adapter/repositories/SqliteClaudeMessageResponseRepository.js.map +1 -0
  11. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +14 -0
  12. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
  13. package/bin/domain/entities/ClaudeMessageResponse.js +3 -0
  14. package/bin/domain/entities/ClaudeMessageResponse.js.map +1 -0
  15. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +18 -11
  16. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  17. package/bin/domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository.js +3 -0
  18. package/bin/domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository.js.map +1 -0
  19. package/package.json +3 -1
  20. package/src/adapter/proxy/ClaudeMessageResponseParser.test.ts +211 -0
  21. package/src/adapter/proxy/ClaudeMessageResponseParser.ts +180 -0
  22. package/src/adapter/proxy/proxyEntry.ts +28 -3
  23. package/src/adapter/repositories/SqliteClaudeMessageResponseRepository.test.ts +313 -0
  24. package/src/adapter/repositories/SqliteClaudeMessageResponseRepository.ts +164 -0
  25. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +27 -0
  26. package/src/domain/entities/ClaudeMessageResponse.ts +31 -0
  27. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +187 -39
  28. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +37 -20
  29. package/src/domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository.ts +5 -0
  30. package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +5 -0
  31. package/types/adapter/proxy/ClaudeMessageResponseParser.d.ts +4 -0
  32. package/types/adapter/proxy/ClaudeMessageResponseParser.d.ts.map +1 -0
  33. package/types/adapter/proxy/proxyEntry.d.ts +2 -1
  34. package/types/adapter/proxy/proxyEntry.d.ts.map +1 -1
  35. package/types/adapter/repositories/SqliteClaudeMessageResponseRepository.d.ts +10 -0
  36. package/types/adapter/repositories/SqliteClaudeMessageResponseRepository.d.ts.map +1 -0
  37. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +1 -0
  38. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
  39. package/types/domain/entities/ClaudeMessageResponse.d.ts +32 -0
  40. package/types/domain/entities/ClaudeMessageResponse.d.ts.map +1 -0
  41. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +3 -2
  42. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  43. package/types/domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository.d.ts +5 -0
  44. package/types/domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository.d.ts.map +1 -0
  45. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +1 -0
  46. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -1
@@ -91,10 +91,10 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
91
91
  get: jest.Mock;
92
92
  update: jest.Mock;
93
93
  updateStatus: jest.Mock;
94
- updateNextActionDate: jest.Mock;
95
94
  findRelatedOpenPRs: jest.Mock;
96
95
  getStoryObjectMap: jest.Mock;
97
96
  getOpenPullRequest: jest.Mock;
97
+ setDependedIssueUrl: jest.Mock;
98
98
  };
99
99
  let mockIssueCommentRepository: {
100
100
  getCommentsFromIssue: jest.Mock;
@@ -119,9 +119,9 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
119
119
  get: jest.fn(),
120
120
  update: jest.fn(),
121
121
  updateStatus: jest.fn(),
122
- updateNextActionDate: jest.fn(),
123
122
  findRelatedOpenPRs: jest.fn(),
124
123
  getOpenPullRequest: jest.fn(),
124
+ setDependedIssueUrl: jest.fn(),
125
125
  };
126
126
 
127
127
  mockIssueCommentRepository = {
@@ -142,9 +142,6 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
142
142
  });
143
143
 
144
144
  it('should update issue status from Preparation to Awaiting Quality Check when last comment starts with From:', async () => {
145
- jest.useFakeTimers();
146
- jest.setSystemTime(new Date('2026-01-01T00:00:00Z'));
147
-
148
145
  const issue = createMockIssue({
149
146
  url: 'https://github.com/user/repo/issues/1',
150
147
  status: 'Preparation',
@@ -191,23 +188,14 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
191
188
  }),
192
189
  'awaiting-quality-check-id',
193
190
  );
194
-
195
- const expectedNextActionDate = new Date('2026-01-01T00:00:00Z');
196
- expectedNextActionDate.setMonth(expectedNextActionDate.getMonth() + 1);
197
- expect(mockIssueRepository.updateNextActionDate).toHaveBeenCalledWith(
191
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
198
192
  'https://github.com/user/repo/pull/1',
199
193
  mockProject,
200
- expectedNextActionDate,
194
+ 'https://github.com/user/repo/issues/1',
201
195
  );
202
-
203
- jest.useRealTimers();
204
196
  });
205
197
 
206
- it('should set PR next action date to 1 month from now when approved', async () => {
207
- jest.useFakeTimers();
208
- const now = new Date('2026-03-15T12:00:00Z');
209
- jest.setSystemTime(now);
210
-
198
+ it('should call setDependedIssueUrl for an approved PR when checks pass', async () => {
211
199
  const issue = createMockIssue({
212
200
  url: 'https://github.com/user/repo/issues/1',
213
201
  status: 'Preparation',
@@ -238,15 +226,11 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
238
226
  workflowBlockerResolvedWebhookUrl: null,
239
227
  });
240
228
 
241
- const expectedDate = new Date(now);
242
- expectedDate.setMonth(expectedDate.getMonth() + 1);
243
- expect(mockIssueRepository.updateNextActionDate).toHaveBeenCalledWith(
229
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
244
230
  prUrl,
245
231
  mockProject,
246
- expectedDate,
232
+ 'https://github.com/user/repo/issues/1',
247
233
  );
248
-
249
- jest.useRealTimers();
250
234
  });
251
235
 
252
236
  it('should throw IssueNotFoundError when issue does not exist', async () => {
@@ -694,11 +678,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
694
678
  );
695
679
  });
696
680
 
697
- it('should use APPROVED escalation wording and set PR next action date when current check passes but threshold is met', async () => {
698
- jest.useFakeTimers();
699
- const now = new Date('2026-02-01T00:00:00Z');
700
- jest.setSystemTime(now);
701
-
681
+ it('should use APPROVED escalation wording and call setDependedIssueUrl when current check passes but threshold is met', async () => {
702
682
  const issue = createMockIssue({
703
683
  url: 'https://github.com/user/repo/issues/1',
704
684
  status: 'Preparation',
@@ -748,15 +728,11 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
748
728
  'Failed to pass the check automatically for 3 times',
749
729
  ),
750
730
  );
751
- const expectedDate = new Date(now);
752
- expectedDate.setMonth(expectedDate.getMonth() + 1);
753
- expect(mockIssueRepository.updateNextActionDate).toHaveBeenCalledWith(
731
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
754
732
  prUrl,
755
733
  mockProject,
756
- expectedDate,
734
+ 'https://github.com/user/repo/issues/1',
757
735
  );
758
-
759
- jest.useRealTimers();
760
736
  });
761
737
 
762
738
  it('should not auto-escalate when rejections are below threshold', async () => {
@@ -1299,6 +1275,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1299
1275
  mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1300
1276
  createMockComment({ content: 'From: Test report' }),
1301
1277
  ]);
1278
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
1302
1279
 
1303
1280
  await useCase.run({
1304
1281
  projectUrl: 'https://github.com/users/user/projects/1',
@@ -1307,7 +1284,6 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1307
1284
  workflowBlockerResolvedWebhookUrl: null,
1308
1285
  });
1309
1286
 
1310
- expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
1311
1287
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
1312
1288
  expect.objectContaining({
1313
1289
  status: 'Awaiting Quality Check',
@@ -1370,6 +1346,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1370
1346
  content: 'Auto Status Check: REJECTED\n["NO_REPORT"]',
1371
1347
  }),
1372
1348
  ]);
1349
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
1373
1350
 
1374
1351
  await useCase.run({
1375
1352
  projectUrl: 'https://github.com/users/user/projects/1',
@@ -1378,7 +1355,6 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1378
1355
  workflowBlockerResolvedWebhookUrl: null,
1379
1356
  });
1380
1357
 
1381
- expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
1382
1358
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
1383
1359
  expect.objectContaining({
1384
1360
  status: 'Awaiting Workspace',
@@ -1405,6 +1381,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1405
1381
  mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1406
1382
  createMockComment({ content: 'From: Test report' }),
1407
1383
  ]);
1384
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
1408
1385
 
1409
1386
  await useCase.run({
1410
1387
  projectUrl: 'https://github.com/users/user/projects/1',
@@ -1413,7 +1390,6 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1413
1390
  workflowBlockerResolvedWebhookUrl: null,
1414
1391
  });
1415
1392
 
1416
- expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
1417
1393
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
1418
1394
  expect.objectContaining({ status: 'Awaiting Quality Check' }),
1419
1395
  mockProject,
@@ -1432,6 +1408,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1432
1408
  mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1433
1409
  createMockComment({ content: 'From: Test report' }),
1434
1410
  ]);
1411
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
1435
1412
 
1436
1413
  await useCase.run({
1437
1414
  projectUrl: 'https://github.com/users/user/projects/1',
@@ -1440,7 +1417,6 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1440
1417
  workflowBlockerResolvedWebhookUrl: null,
1441
1418
  });
1442
1419
 
1443
- expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
1444
1420
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
1445
1421
  expect.objectContaining({ status: 'Awaiting Quality Check' }),
1446
1422
  mockProject,
@@ -1461,6 +1437,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1461
1437
  content: 'Auto Status Check: REJECTED\n["NO_REPORT"]',
1462
1438
  }),
1463
1439
  ]);
1440
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
1464
1441
 
1465
1442
  await useCase.run({
1466
1443
  projectUrl: 'https://github.com/users/user/projects/1',
@@ -1469,7 +1446,6 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1469
1446
  workflowBlockerResolvedWebhookUrl: null,
1470
1447
  });
1471
1448
 
1472
- expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
1473
1449
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
1474
1450
  expect.objectContaining({ status: 'Awaiting Workspace' }),
1475
1451
  mockProject,
@@ -1519,6 +1495,178 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1519
1495
  );
1520
1496
  });
1521
1497
 
1498
+ describe('setDependedIssueUrl for open PRs', () => {
1499
+ it('should call setDependedIssueUrl for a non-approved PR', async () => {
1500
+ const issue = createMockIssue({
1501
+ url: 'https://github.com/user/repo/issues/1',
1502
+ status: 'Preparation',
1503
+ });
1504
+ const prUrl = 'https://github.com/user/repo/pull/10';
1505
+
1506
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1507
+ mockIssueRepository.get.mockResolvedValue(issue);
1508
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1509
+ createMockComment({ content: 'From: Agent report' }),
1510
+ ]);
1511
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1512
+ {
1513
+ url: prUrl,
1514
+ isConflicted: false,
1515
+ isPassedAllCiJob: false,
1516
+ isCiStateSuccess: false,
1517
+ isResolvedAllReviewComments: true,
1518
+ isBranchOutOfDate: false,
1519
+ missingRequiredCheckNames: [],
1520
+ },
1521
+ ]);
1522
+
1523
+ await useCase.run({
1524
+ projectUrl: 'https://github.com/users/user/projects/1',
1525
+ issueUrl: 'https://github.com/user/repo/issues/1',
1526
+ thresholdForAutoReject: 3,
1527
+ workflowBlockerResolvedWebhookUrl: null,
1528
+ });
1529
+
1530
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
1531
+ prUrl,
1532
+ mockProject,
1533
+ 'https://github.com/user/repo/issues/1',
1534
+ );
1535
+ });
1536
+
1537
+ it('should call setDependedIssueUrl for an approved PR', async () => {
1538
+ const issue = createMockIssue({
1539
+ url: 'https://github.com/user/repo/issues/1',
1540
+ status: 'Preparation',
1541
+ });
1542
+ const prUrl = 'https://github.com/user/repo/pull/20';
1543
+
1544
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1545
+ mockIssueRepository.get.mockResolvedValue(issue);
1546
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1547
+ createMockComment({ content: 'From: Agent report' }),
1548
+ ]);
1549
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1550
+ {
1551
+ url: prUrl,
1552
+ isConflicted: false,
1553
+ isPassedAllCiJob: true,
1554
+ isCiStateSuccess: true,
1555
+ isResolvedAllReviewComments: true,
1556
+ isBranchOutOfDate: false,
1557
+ missingRequiredCheckNames: [],
1558
+ },
1559
+ ]);
1560
+
1561
+ await useCase.run({
1562
+ projectUrl: 'https://github.com/users/user/projects/1',
1563
+ issueUrl: 'https://github.com/user/repo/issues/1',
1564
+ thresholdForAutoReject: 3,
1565
+ workflowBlockerResolvedWebhookUrl: null,
1566
+ });
1567
+
1568
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
1569
+ prUrl,
1570
+ mockProject,
1571
+ 'https://github.com/user/repo/issues/1',
1572
+ );
1573
+ });
1574
+
1575
+ it('should call setDependedIssueUrl for multiple PRs when multiple are linked to the issue', async () => {
1576
+ const issue = createMockIssue({
1577
+ url: 'https://github.com/user/repo/issues/1',
1578
+ status: 'Preparation',
1579
+ });
1580
+ const prUrl1 = 'https://github.com/user/repo/pull/30';
1581
+ const prUrl2 = 'https://github.com/user/repo/pull/31';
1582
+
1583
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1584
+ mockIssueRepository.get.mockResolvedValue(issue);
1585
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1586
+ createMockComment({ content: 'From: Agent report' }),
1587
+ ]);
1588
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1589
+ {
1590
+ url: prUrl1,
1591
+ isConflicted: false,
1592
+ isPassedAllCiJob: true,
1593
+ isCiStateSuccess: true,
1594
+ isResolvedAllReviewComments: true,
1595
+ isBranchOutOfDate: false,
1596
+ missingRequiredCheckNames: [],
1597
+ },
1598
+ {
1599
+ url: prUrl2,
1600
+ isConflicted: true,
1601
+ isPassedAllCiJob: false,
1602
+ isCiStateSuccess: false,
1603
+ isResolvedAllReviewComments: false,
1604
+ isBranchOutOfDate: false,
1605
+ missingRequiredCheckNames: [],
1606
+ },
1607
+ ]);
1608
+
1609
+ await useCase.run({
1610
+ projectUrl: 'https://github.com/users/user/projects/1',
1611
+ issueUrl: 'https://github.com/user/repo/issues/1',
1612
+ thresholdForAutoReject: 3,
1613
+ workflowBlockerResolvedWebhookUrl: null,
1614
+ });
1615
+
1616
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
1617
+ prUrl1,
1618
+ mockProject,
1619
+ 'https://github.com/user/repo/issues/1',
1620
+ );
1621
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
1622
+ prUrl2,
1623
+ mockProject,
1624
+ 'https://github.com/user/repo/issues/1',
1625
+ );
1626
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledTimes(2);
1627
+ });
1628
+
1629
+ it('should delegate the skip-if-already-set check to the repository (setDependedIssueUrl is always called per PR)', async () => {
1630
+ const issue = createMockIssue({
1631
+ url: 'https://github.com/user/repo/issues/1',
1632
+ status: 'Preparation',
1633
+ });
1634
+ const prUrl = 'https://github.com/user/repo/pull/40';
1635
+
1636
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1637
+ mockIssueRepository.get.mockResolvedValue(issue);
1638
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1639
+ createMockComment({ content: 'From: Agent report' }),
1640
+ ]);
1641
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1642
+ {
1643
+ url: prUrl,
1644
+ isConflicted: false,
1645
+ isPassedAllCiJob: true,
1646
+ isCiStateSuccess: true,
1647
+ isResolvedAllReviewComments: true,
1648
+ isBranchOutOfDate: false,
1649
+ missingRequiredCheckNames: [],
1650
+ },
1651
+ ]);
1652
+ mockIssueRepository.setDependedIssueUrl.mockResolvedValue(undefined);
1653
+
1654
+ await useCase.run({
1655
+ projectUrl: 'https://github.com/users/user/projects/1',
1656
+ issueUrl: 'https://github.com/user/repo/issues/1',
1657
+ thresholdForAutoReject: 3,
1658
+ workflowBlockerResolvedWebhookUrl: null,
1659
+ });
1660
+
1661
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledTimes(1);
1662
+ expect(mockIssueRepository.setDependedIssueUrl).toHaveBeenCalledWith(
1663
+ prUrl,
1664
+ mockProject,
1665
+ 'https://github.com/user/repo/issues/1',
1666
+ );
1667
+ });
1668
+ });
1669
+
1522
1670
  describe('workflow blocker webhook notification', () => {
1523
1671
  const createWorkflowBlockerStoryObjectMap = (
1524
1672
  issueUrl: string,
@@ -46,10 +46,10 @@ export class NotifyFinishedIssuePreparationUseCase {
46
46
  | 'get'
47
47
  | 'update'
48
48
  | 'updateStatus'
49
- | 'updateNextActionDate'
50
49
  | 'findRelatedOpenPRs'
51
50
  | 'getStoryObjectMap'
52
51
  | 'getOpenPullRequest'
52
+ | 'setDependedIssueUrl'
53
53
  >,
54
54
  private readonly issueCommentRepository: Pick<
55
55
  IssueCommentRepository,
@@ -167,10 +167,7 @@ export class NotifyFinishedIssuePreparationUseCase {
167
167
  const comments =
168
168
  await this.issueCommentRepository.getCommentsFromIssue(issue);
169
169
 
170
- const { rejections, approvedPrUrl } = await this.collectRejections(
171
- issue,
172
- comments,
173
- );
170
+ const { rejections } = await this.collectRejections(issue, comments);
174
171
 
175
172
  const rejectionStatusMessage =
176
173
  rejections.length > 0
@@ -201,9 +198,11 @@ export class NotifyFinishedIssuePreparationUseCase {
201
198
  rejections.length > 0
202
199
  ? rejectionStatusMessage
203
200
  : 'Auto Status Check: APPROVED (escalated due to prior failures)';
204
- if (rejections.length === 0 && approvedPrUrl !== null) {
205
- await this.setPrNextActionDate(approvedPrUrl, project);
206
- }
201
+ await this.setDependedIssueUrlForAllOpenPRs(
202
+ issue,
203
+ params.issueUrl,
204
+ project,
205
+ );
207
206
  await this.issueCommentRepository.createComment(
208
207
  issue,
209
208
  `${escalationStatusLine}\n\nFailed to pass the check automatically for ${params.thresholdForAutoReject} times`,
@@ -224,9 +223,11 @@ export class NotifyFinishedIssuePreparationUseCase {
224
223
  issue,
225
224
  awaitingQualityCheckStatusOption.id,
226
225
  );
227
- if (approvedPrUrl !== null) {
228
- await this.setPrNextActionDate(approvedPrUrl, project);
229
- }
226
+ await this.setDependedIssueUrlForAllOpenPRs(
227
+ issue,
228
+ params.issueUrl,
229
+ project,
230
+ );
230
231
  await this.sendWorkflowBlockerNotification(
231
232
  params.issueUrl,
232
233
  params.workflowBlockerResolvedWebhookUrl,
@@ -243,6 +244,12 @@ export class NotifyFinishedIssuePreparationUseCase {
243
244
  awaitingWorkspaceStatusOption.id,
244
245
  );
245
246
 
247
+ await this.setDependedIssueUrlForAllOpenPRs(
248
+ issue,
249
+ params.issueUrl,
250
+ project,
251
+ );
252
+
246
253
  await this.issueCommentRepository.createComment(
247
254
  issue,
248
255
  rejectionStatusMessage,
@@ -301,17 +308,27 @@ export class NotifyFinishedIssuePreparationUseCase {
301
308
  return nextStepValue !== null && nextStepValue !== undefined;
302
309
  };
303
310
 
304
- private setPrNextActionDate = async (
305
- prUrl: string,
311
+ private setDependedIssueUrlForAllOpenPRs = async (
312
+ issue: { url: string; labels: string[]; isPr: boolean },
313
+ issueUrl: string,
306
314
  project: Parameters<IssueRepository['get']>[1],
307
315
  ): Promise<void> => {
308
- const nextActionDate = new Date();
309
- nextActionDate.setMonth(nextActionDate.getMonth() + 1);
310
- await this.issueRepository.updateNextActionDate(
311
- prUrl,
312
- project,
313
- nextActionDate,
314
- );
316
+ const openPRs = issue.isPr
317
+ ? await this.resolveOpenPrsForPrItem(issue.url)
318
+ : await this.issueRepository.findRelatedOpenPRs(issue.url);
319
+ for (const pr of openPRs) {
320
+ await this.issueRepository.setDependedIssueUrl(pr.url, project, issueUrl);
321
+ }
322
+ };
323
+
324
+ private resolveOpenPrsForPrItem = async (
325
+ prUrl: string,
326
+ ): Promise<{ url: string }[]> => {
327
+ const pr = await this.issueRepository.getOpenPullRequest(prUrl);
328
+ if (pr === null) {
329
+ return [];
330
+ }
331
+ return [pr];
315
332
  };
316
333
 
317
334
  private sendWorkflowBlockerNotification = async (
@@ -0,0 +1,5 @@
1
+ import { ClaudeMessageResponse } from '../../entities/ClaudeMessageResponse';
2
+
3
+ export interface ClaudeMessageResponseRepository {
4
+ append: (response: ClaudeMessageResponse) => void;
5
+ }
@@ -86,4 +86,9 @@ export interface IssueRepository {
86
86
  allowCacheMinutes: number,
87
87
  ) => Promise<StoryObjectMap>;
88
88
  addIssueToProject: (project: Project, issueUrl: string) => Promise<void>;
89
+ setDependedIssueUrl: (
90
+ prUrl: string,
91
+ project: Project,
92
+ issueUrl: string,
93
+ ) => Promise<void>;
89
94
  }
@@ -0,0 +1,4 @@
1
+ import * as http from 'http';
2
+ import { ClaudeMessageResponse } from '../../domain/entities/ClaudeMessageResponse';
3
+ export declare const parseClaudeMessageResponse: (tokenName: string, httpStatus: number, headers: http.IncomingHttpHeaders, body: string) => ClaudeMessageResponse;
4
+ //# sourceMappingURL=ClaudeMessageResponseParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeMessageResponseParser.d.ts","sourceRoot":"","sources":["../../../src/adapter/proxy/ClaudeMessageResponseParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AAiFpF,eAAO,MAAM,0BAA0B,GACrC,WAAW,MAAM,EACjB,YAAY,MAAM,EAClB,SAAS,IAAI,CAAC,mBAAmB,EACjC,MAAM,MAAM,KACX,qBA4FF,CAAC"}
@@ -1,4 +1,5 @@
1
+ import { ClaudeMessageResponseRepository } from '../../domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository';
1
2
  declare const extractToken: (authorization: string | string[] | undefined) => string | null;
2
- declare const startProxy: (port: number) => void;
3
+ declare const startProxy: (port: number, claudeMessageResponseRepository?: ClaudeMessageResponseRepository | null) => void;
3
4
  export { startProxy, extractToken };
4
5
  //# sourceMappingURL=proxyEntry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxyEntry.d.ts","sourceRoot":"","sources":["../../../src/adapter/proxy/proxyEntry.ts"],"names":[],"mappings":"AAeA,QAAA,MAAM,YAAY,GAChB,eAAe,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,KAC3C,MAAM,GAAG,IAQX,CAAC;AAEF,QAAA,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,IA0DlC,CAAC;AAMF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"proxyEntry.d.ts","sourceRoot":"","sources":["../../../src/adapter/proxy/proxyEntry.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,+BAA+B,EAAE,MAAM,0EAA0E,CAAC;AAU3H,QAAA,MAAM,YAAY,GAChB,eAAe,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,KAC3C,MAAM,GAAG,IAQX,CAAC;AAEF,QAAA,MAAM,UAAU,GACd,MAAM,MAAM,EACZ,kCAAiC,+BAA+B,GAAG,IAAW,KAC7E,IA0EF,CAAC;AAQF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { ClaudeMessageResponse } from '../../domain/entities/ClaudeMessageResponse';
2
+ import { ClaudeMessageResponseRepository } from '../../domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository';
3
+ export declare const generateUlid: () => string;
4
+ export declare class SqliteClaudeMessageResponseRepository implements ClaudeMessageResponseRepository {
5
+ private readonly db;
6
+ private readonly insert;
7
+ constructor(dbPath: string);
8
+ append: (response: ClaudeMessageResponse) => void;
9
+ }
10
+ //# sourceMappingURL=SqliteClaudeMessageResponseRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqliteClaudeMessageResponseRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/SqliteClaudeMessageResponseRepository.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EAAE,+BAA+B,EAAE,MAAM,0EAA0E,CAAC;AA6B3H,eAAO,MAAM,YAAY,QAAO,MACiB,CAAC;AA0ElD,qBAAa,qCAAsC,YAAW,+BAA+B;IAC3F,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAEhC,MAAM,EAAE,MAAM;IAW1B,MAAM,GAAI,UAAU,qBAAqB,KAAG,IAAI,CAsC9C;CACH"}
@@ -33,6 +33,7 @@ export declare class ApiV3CheerioRestIssueRepository extends BaseGitHubRepositor
33
33
  updateIssue: (issue: Issue) => Promise<void>;
34
34
  getIssueByUrl: (url: string) => Promise<Issue | null>;
35
35
  addIssueToProject: (project: Project, issueUrl: string) => Promise<void>;
36
+ setDependedIssueUrl: (prUrl: string, project: Project, issueUrl: string) => Promise<void>;
36
37
  updateNextActionDate: (issueUrl: string, project: Project, date: Date) => Promise<void>;
37
38
  updateNextActionHour: (project: Project & {
38
39
  nextActionHour: NonNullable<Project["nextActionHour"]>;
@@ -1 +1 @@
1
- {"version":3,"file":"ApiV3CheerioRestIssueRepository.d.ts","sourceRoot":"","sources":["../../../../src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ApiV3CheerioRestIssueRepository.d.ts","sourceRoot":"","sources":["../../../../src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export type ClaudeMessageResponse = {
2
+ id: string;
3
+ observedAt: Date;
4
+ tokenName: string;
5
+ externalClaudeMessageId: string | null;
6
+ externalClaudeRequestId: string | null;
7
+ httpStatus: number;
8
+ model: string | null;
9
+ role: string | null;
10
+ stopReason: string | null;
11
+ stopSequence: string | null;
12
+ inputTokens: number | null;
13
+ outputTokens: number | null;
14
+ cacheCreationInputTokens: number | null;
15
+ cacheReadInputTokens: number | null;
16
+ ephemeral5mInputTokens: number | null;
17
+ ephemeral1hInputTokens: number | null;
18
+ serviceTier: string | null;
19
+ inferenceGeo: string | null;
20
+ errorType: string | null;
21
+ errorMessage: string | null;
22
+ anthropicRatelimitUnifiedStatus: string | null;
23
+ anthropicRatelimitUnified5hStatus: string | null;
24
+ anthropicRatelimitUnified5hUtilization: number | null;
25
+ anthropicRatelimitUnified5hReset: number | null;
26
+ anthropicRatelimitUnified7dStatus: string | null;
27
+ anthropicRatelimitUnified7dUtilization: number | null;
28
+ anthropicRatelimitUnified7dReset: number | null;
29
+ retryAfter: number | null;
30
+ anthropicOrganizationId: string | null;
31
+ };
32
+ //# sourceMappingURL=ClaudeMessageResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeMessageResponse.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/ClaudeMessageResponse.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+BAA+B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,iCAAiC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,sCAAsC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,gCAAgC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,iCAAiC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,sCAAsC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,gCAAgC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC,CAAC"}
@@ -14,7 +14,7 @@ export declare class NotifyFinishedIssuePreparationUseCase {
14
14
  private readonly issueCommentRepository;
15
15
  private readonly webhookRepository;
16
16
  private readonly issueRejectionEvaluator;
17
- constructor(projectRepository: Pick<ProjectRepository, 'getByUrl'>, issueRepository: Pick<IssueRepository, 'get' | 'update' | 'updateStatus' | 'updateNextActionDate' | 'findRelatedOpenPRs' | 'getStoryObjectMap' | 'getOpenPullRequest'>, issueCommentRepository: Pick<IssueCommentRepository, 'getCommentsFromIssue' | 'createComment'>, webhookRepository: Pick<WebhookRepository, 'sendGetRequest'>);
17
+ constructor(projectRepository: Pick<ProjectRepository, 'getByUrl'>, issueRepository: Pick<IssueRepository, 'get' | 'update' | 'updateStatus' | 'findRelatedOpenPRs' | 'getStoryObjectMap' | 'getOpenPullRequest' | 'setDependedIssueUrl'>, issueCommentRepository: Pick<IssueCommentRepository, 'getCommentsFromIssue' | 'createComment'>, webhookRepository: Pick<WebhookRepository, 'sendGetRequest'>);
18
18
  run: (params: {
19
19
  projectUrl: string;
20
20
  issueUrl: string;
@@ -23,7 +23,8 @@ export declare class NotifyFinishedIssuePreparationUseCase {
23
23
  }) => Promise<void>;
24
24
  private collectRejections;
25
25
  private reportBodyHasNextStep;
26
- private setPrNextActionDate;
26
+ private setDependedIssueUrlForAllOpenPRs;
27
+ private resolveOpenPrsForPrItem;
27
28
  private sendWorkflowBlockerNotification;
28
29
  }
29
30
  //# sourceMappingURL=NotifyFinishedIssuePreparationUseCase.d.ts.map
@@ -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;AAY3E,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;AAMD,qBAAa,qCAAqC;IAI9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAUhC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAIvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAlBpC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA0B;gBAG/C,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,KAAK,GACL,QAAQ,GACR,cAAc,GACd,sBAAsB,GACtB,oBAAoB,GACpB,mBAAmB,GACnB,oBAAoB,CACvB,EACgB,sBAAsB,EAAE,IAAI,CAC3C,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC,EACgB,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,gBAAgB,CACjB;IAKH,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;KAClD,KAAG,OAAO,CAAC,IAAI,CAAC,CAmLf;IAEF,OAAO,CAAC,iBAAiB,CAyBvB;IAEF,OAAO,CAAC,qBAAqB,CAuB3B;IAEF,OAAO,CAAC,mBAAmB,CAWzB;IAEF,OAAO,CAAC,+BAA+B,CAkCrC;CACH"}
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;AAY3E,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;AAMD,qBAAa,qCAAqC;IAI9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAUhC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAIvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAlBpC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA0B;gBAG/C,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,KAAK,GACL,QAAQ,GACR,cAAc,GACd,oBAAoB,GACpB,mBAAmB,GACnB,oBAAoB,GACpB,qBAAqB,CACxB,EACgB,sBAAsB,EAAE,IAAI,CAC3C,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC,EACgB,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,gBAAgB,CACjB;IAKH,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;KAClD,KAAG,OAAO,CAAC,IAAI,CAAC,CA0Lf;IAEF,OAAO,CAAC,iBAAiB,CAyBvB;IAEF,OAAO,CAAC,qBAAqB,CAuB3B;IAEF,OAAO,CAAC,gCAAgC,CAWtC;IAEF,OAAO,CAAC,uBAAuB,CAQ7B;IAEF,OAAO,CAAC,+BAA+B,CAkCrC;CACH"}
@@ -0,0 +1,5 @@
1
+ import { ClaudeMessageResponse } from '../../entities/ClaudeMessageResponse';
2
+ export interface ClaudeMessageResponseRepository {
3
+ append: (response: ClaudeMessageResponse) => void;
4
+ }
5
+ //# sourceMappingURL=ClaudeMessageResponseRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeMessageResponseRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACnD"}
@@ -45,5 +45,6 @@ export interface IssueRepository {
45
45
  getAllOpened: (project: Project) => Promise<Issue[]>;
46
46
  getStoryObjectMap: (project: Project, allowCacheMinutes: number) => Promise<StoryObjectMap>;
47
47
  addIssueToProject: (project: Project, issueUrl: string) => Promise<void>;
48
+ setDependedIssueUrl: (prUrl: string, project: Project, issueUrl: string) => Promise<void>;
48
49
  }
49
50
  //# sourceMappingURL=IssueRepository.d.ts.map