github-issue-tower-defence-management 1.73.3 → 1.74.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 (28) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +3 -0
  3. package/bin/adapter/entry-points/cli/index.js +3 -0
  4. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  5. package/bin/adapter/entry-points/cli/projectConfig.js +6 -0
  6. package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
  7. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +8 -2
  8. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  9. package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -0
  10. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
  11. package/bin/domain/usecases/StartPreparationUseCase.js +21 -5
  12. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  13. package/package.json +1 -1
  14. package/src/adapter/entry-points/cli/index.test.ts +2 -0
  15. package/src/adapter/entry-points/cli/index.ts +7 -0
  16. package/src/adapter/entry-points/cli/projectConfig.ts +8 -0
  17. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +3 -0
  18. package/src/domain/usecases/HandleScheduledEventUseCase.ts +3 -0
  19. package/src/domain/usecases/StartPreparationUseCase.test.ts +409 -0
  20. package/src/domain/usecases/StartPreparationUseCase.ts +32 -4
  21. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  22. package/types/adapter/entry-points/cli/projectConfig.d.ts +1 -0
  23. package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
  24. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  25. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +1 -0
  26. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
  27. package/types/domain/usecases/StartPreparationUseCase.d.ts +2 -0
  28. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
@@ -146,6 +146,7 @@ describe('StartPreparationUseCase', () => {
146
146
  projectUrl: 'https://github.com/user/repo',
147
147
  defaultAgentName: 'agent1',
148
148
  defaultLlmModelName: 'claude-opus',
149
+ fallbackLlmModelName: null,
149
150
  defaultLlmAgentName: null,
150
151
  configFilePath: '/path/to/config.yml',
151
152
  maximumPreparingIssuesCount: null,
@@ -211,6 +212,7 @@ describe('StartPreparationUseCase', () => {
211
212
  projectUrl: 'https://github.com/user/repo',
212
213
  defaultAgentName: 'agent1',
213
214
  defaultLlmModelName: 'claude-opus',
215
+ fallbackLlmModelName: null,
214
216
  defaultLlmAgentName: null,
215
217
  configFilePath: '/path/to/config.yml',
216
218
  maximumPreparingIssuesCount: null,
@@ -268,6 +270,7 @@ describe('StartPreparationUseCase', () => {
268
270
  projectUrl: 'https://github.com/user/repo',
269
271
  defaultAgentName: 'agent1',
270
272
  defaultLlmModelName: 'claude-opus',
273
+ fallbackLlmModelName: null,
271
274
  defaultLlmAgentName: null,
272
275
  configFilePath: '/path/to/config.yml',
273
276
  maximumPreparingIssuesCount: null,
@@ -316,6 +319,7 @@ describe('StartPreparationUseCase', () => {
316
319
  projectUrl: 'https://github.com/user/repo',
317
320
  defaultAgentName: 'agent1',
318
321
  defaultLlmModelName: 'claude-opus',
322
+ fallbackLlmModelName: null,
319
323
  defaultLlmAgentName: null,
320
324
  configFilePath: '/path/to/config.yml',
321
325
  maximumPreparingIssuesCount: null,
@@ -365,6 +369,7 @@ describe('StartPreparationUseCase', () => {
365
369
  projectUrl: 'https://github.com/user/repo',
366
370
  defaultAgentName: 'agent1',
367
371
  defaultLlmModelName: 'claude-opus',
372
+ fallbackLlmModelName: null,
368
373
  defaultLlmAgentName: null,
369
374
  configFilePath: '/path/to/config.yml',
370
375
  maximumPreparingIssuesCount: null,
@@ -413,6 +418,7 @@ describe('StartPreparationUseCase', () => {
413
418
  projectUrl: 'https://github.com/user/repo',
414
419
  defaultAgentName: 'agent1',
415
420
  defaultLlmModelName: 'claude-opus',
421
+ fallbackLlmModelName: null,
416
422
  defaultLlmAgentName: null,
417
423
  configFilePath: '/path/to/config.yml',
418
424
  maximumPreparingIssuesCount: null,
@@ -479,6 +485,7 @@ describe('StartPreparationUseCase', () => {
479
485
  projectUrl: 'https://github.com/user/repo',
480
486
  defaultAgentName: 'agent1',
481
487
  defaultLlmModelName: 'claude-opus',
488
+ fallbackLlmModelName: null,
482
489
  defaultLlmAgentName: null,
483
490
  configFilePath: '/path/to/config.yml',
484
491
  maximumPreparingIssuesCount: null,
@@ -568,6 +575,7 @@ describe('StartPreparationUseCase', () => {
568
575
  projectUrl: 'https://github.com/user/repo',
569
576
  defaultAgentName: 'agent1',
570
577
  defaultLlmModelName: 'claude-opus',
578
+ fallbackLlmModelName: null,
571
579
  defaultLlmAgentName: null,
572
580
  configFilePath: '/path/to/config.yml',
573
581
  maximumPreparingIssuesCount: null,
@@ -631,6 +639,7 @@ describe('StartPreparationUseCase', () => {
631
639
  projectUrl: 'https://github.com/user/repo',
632
640
  defaultAgentName: 'agent1',
633
641
  defaultLlmModelName: 'claude-opus',
642
+ fallbackLlmModelName: null,
634
643
  defaultLlmAgentName: null,
635
644
  configFilePath: '/path/to/config.yml',
636
645
  maximumPreparingIssuesCount: null,
@@ -675,6 +684,7 @@ describe('StartPreparationUseCase', () => {
675
684
  projectUrl: 'https://github.com/user/repo',
676
685
  defaultAgentName: 'agent1',
677
686
  defaultLlmModelName: 'claude-sonnet-4-6',
687
+ fallbackLlmModelName: null,
678
688
  defaultLlmAgentName: null,
679
689
  configFilePath: '/path/to/config.yml',
680
690
  maximumPreparingIssuesCount: null,
@@ -732,6 +742,7 @@ describe('StartPreparationUseCase', () => {
732
742
  projectUrl: 'https://github.com/user/repo',
733
743
  defaultAgentName: 'agent1',
734
744
  defaultLlmModelName: null,
745
+ fallbackLlmModelName: null,
735
746
  defaultLlmAgentName: null,
736
747
  configFilePath: '/path/to/config.yml',
737
748
  maximumPreparingIssuesCount: null,
@@ -767,6 +778,7 @@ describe('StartPreparationUseCase', () => {
767
778
  projectUrl: 'https://github.com/user/repo',
768
779
  defaultAgentName: 'agent1',
769
780
  defaultLlmModelName: 'claude-opus',
781
+ fallbackLlmModelName: null,
770
782
  defaultLlmAgentName: null,
771
783
  configFilePath: '/path/to/config.yml',
772
784
  maximumPreparingIssuesCount: null,
@@ -812,6 +824,7 @@ describe('StartPreparationUseCase', () => {
812
824
  projectUrl: 'https://github.com/user/repo',
813
825
  defaultAgentName: 'agent1',
814
826
  defaultLlmModelName: 'claude-opus',
827
+ fallbackLlmModelName: null,
815
828
  defaultLlmAgentName: null,
816
829
  configFilePath: '/path/to/config.yml',
817
830
  maximumPreparingIssuesCount: null,
@@ -857,6 +870,7 @@ describe('StartPreparationUseCase', () => {
857
870
  projectUrl: 'https://github.com/user/repo',
858
871
  defaultAgentName: 'agent1',
859
872
  defaultLlmModelName: 'claude-sonnet-4-6',
873
+ fallbackLlmModelName: null,
860
874
  defaultLlmAgentName: 'default-llm-agent',
861
875
  configFilePath: '/path/to/config.yml',
862
876
  maximumPreparingIssuesCount: null,
@@ -902,6 +916,7 @@ describe('StartPreparationUseCase', () => {
902
916
  projectUrl: 'https://github.com/user/repo',
903
917
  defaultAgentName: 'agent1',
904
918
  defaultLlmModelName: 'claude-sonnet-4-6',
919
+ fallbackLlmModelName: null,
905
920
  defaultLlmAgentName: 'default-llm-agent',
906
921
  configFilePath: '/path/to/config.yml',
907
922
  maximumPreparingIssuesCount: null,
@@ -947,6 +962,7 @@ describe('StartPreparationUseCase', () => {
947
962
  projectUrl: 'https://github.com/user/repo',
948
963
  defaultAgentName: 'agent1',
949
964
  defaultLlmModelName: 'claude-sonnet-4-6',
965
+ fallbackLlmModelName: null,
950
966
  defaultLlmAgentName: 'default-llm-agent',
951
967
  configFilePath: '/path/to/config.yml',
952
968
  maximumPreparingIssuesCount: null,
@@ -992,6 +1008,7 @@ describe('StartPreparationUseCase', () => {
992
1008
  projectUrl: 'https://github.com/user/repo',
993
1009
  defaultAgentName: 'agent1',
994
1010
  defaultLlmModelName: 'claude-opus',
1011
+ fallbackLlmModelName: null,
995
1012
  defaultLlmAgentName: null,
996
1013
  configFilePath: '/path/to/config.yml',
997
1014
  maximumPreparingIssuesCount: null,
@@ -1040,6 +1057,7 @@ describe('StartPreparationUseCase', () => {
1040
1057
  projectUrl: 'https://github.com/user/repo',
1041
1058
  defaultAgentName: 'agent1',
1042
1059
  defaultLlmModelName: null,
1060
+ fallbackLlmModelName: null,
1043
1061
  defaultLlmAgentName: null,
1044
1062
  configFilePath: '/path/to/config.yml',
1045
1063
  maximumPreparingIssuesCount: null,
@@ -1088,6 +1106,7 @@ describe('StartPreparationUseCase', () => {
1088
1106
  projectUrl: 'https://github.com/user/repo',
1089
1107
  defaultAgentName: 'agent1',
1090
1108
  defaultLlmModelName: null,
1109
+ fallbackLlmModelName: null,
1091
1110
  defaultLlmAgentName: null,
1092
1111
  configFilePath: '/path/to/config.yml',
1093
1112
  maximumPreparingIssuesCount: null,
@@ -1138,6 +1157,7 @@ describe('StartPreparationUseCase', () => {
1138
1157
  projectUrl: 'https://github.com/user/repo',
1139
1158
  defaultAgentName: 'agent1',
1140
1159
  defaultLlmModelName: null,
1160
+ fallbackLlmModelName: null,
1141
1161
  defaultLlmAgentName: null,
1142
1162
  configFilePath: '/path/to/config.yml',
1143
1163
  maximumPreparingIssuesCount: null,
@@ -1173,6 +1193,7 @@ describe('StartPreparationUseCase', () => {
1173
1193
  projectUrl: 'https://github.com/user/repo',
1174
1194
  defaultAgentName: 'agent1',
1175
1195
  defaultLlmModelName: 'claude-sonnet-4-6',
1196
+ fallbackLlmModelName: null,
1176
1197
  defaultLlmAgentName: null,
1177
1198
  configFilePath: '/path/to/config.yml',
1178
1199
  maximumPreparingIssuesCount: 3,
@@ -1207,6 +1228,7 @@ describe('StartPreparationUseCase', () => {
1207
1228
  projectUrl: 'https://github.com/user/repo',
1208
1229
  defaultAgentName: 'agent1',
1209
1230
  defaultLlmModelName: 'claude-sonnet-4-6',
1231
+ fallbackLlmModelName: null,
1210
1232
  defaultLlmAgentName: null,
1211
1233
  configFilePath: '/path/to/config.yml',
1212
1234
  maximumPreparingIssuesCount: null,
@@ -1264,6 +1286,7 @@ describe('StartPreparationUseCase', () => {
1264
1286
  projectUrl: 'https://github.com/user/repo',
1265
1287
  defaultAgentName: 'agent1',
1266
1288
  defaultLlmModelName: 'claude-sonnet-4-6',
1289
+ fallbackLlmModelName: null,
1267
1290
  defaultLlmAgentName: null,
1268
1291
  configFilePath: '/path/to/config.yml',
1269
1292
  maximumPreparingIssuesCount: 12,
@@ -1330,6 +1353,7 @@ describe('StartPreparationUseCase', () => {
1330
1353
  projectUrl: 'https://github.com/user/repo',
1331
1354
  defaultAgentName: 'agent1',
1332
1355
  defaultLlmModelName: 'claude-sonnet-4-6',
1356
+ fallbackLlmModelName: null,
1333
1357
  defaultLlmAgentName: null,
1334
1358
  configFilePath: '/path/to/config.yml',
1335
1359
  maximumPreparingIssuesCount: 20,
@@ -1394,6 +1418,7 @@ describe('StartPreparationUseCase', () => {
1394
1418
  projectUrl: 'https://github.com/user/repo',
1395
1419
  defaultAgentName: 'agent1',
1396
1420
  defaultLlmModelName: 'claude-sonnet-4-6',
1421
+ fallbackLlmModelName: null,
1397
1422
  defaultLlmAgentName: null,
1398
1423
  configFilePath: '/path/to/config.yml',
1399
1424
  maximumPreparingIssuesCount: null,
@@ -1442,6 +1467,7 @@ describe('StartPreparationUseCase', () => {
1442
1467
  projectUrl: 'https://github.com/user/repo',
1443
1468
  defaultAgentName: 'agent1',
1444
1469
  defaultLlmModelName: 'claude-sonnet-4-6',
1470
+ fallbackLlmModelName: null,
1445
1471
  defaultLlmAgentName: null,
1446
1472
  configFilePath: '/path/to/config.yml',
1447
1473
  maximumPreparingIssuesCount: null,
@@ -1497,6 +1523,7 @@ describe('StartPreparationUseCase', () => {
1497
1523
  projectUrl: 'https://github.com/user/repo',
1498
1524
  defaultAgentName: 'agent1',
1499
1525
  defaultLlmModelName: 'claude-sonnet-4-6',
1526
+ fallbackLlmModelName: null,
1500
1527
  defaultLlmAgentName: null,
1501
1528
  configFilePath: '/path/to/config.yml',
1502
1529
  maximumPreparingIssuesCount: null,
@@ -1555,6 +1582,7 @@ describe('StartPreparationUseCase', () => {
1555
1582
  projectUrl: 'https://github.com/user/repo',
1556
1583
  defaultAgentName: 'agent1',
1557
1584
  defaultLlmModelName: 'claude-sonnet-4-6',
1585
+ fallbackLlmModelName: null,
1558
1586
  defaultLlmAgentName: null,
1559
1587
  configFilePath: '/path/to/config.yml',
1560
1588
  maximumPreparingIssuesCount: null,
@@ -1603,6 +1631,7 @@ describe('StartPreparationUseCase', () => {
1603
1631
  projectUrl: 'https://github.com/user/repo',
1604
1632
  defaultAgentName: 'agent1',
1605
1633
  defaultLlmModelName: 'claude-sonnet-4-6',
1634
+ fallbackLlmModelName: null,
1606
1635
  defaultLlmAgentName: null,
1607
1636
  configFilePath: '/path/to/config.yml',
1608
1637
  maximumPreparingIssuesCount: null,
@@ -1651,6 +1680,7 @@ describe('StartPreparationUseCase', () => {
1651
1680
  projectUrl: 'https://github.com/user/repo',
1652
1681
  defaultAgentName: 'agent1',
1653
1682
  defaultLlmModelName: 'claude-sonnet-4-6',
1683
+ fallbackLlmModelName: null,
1654
1684
  defaultLlmAgentName: null,
1655
1685
  configFilePath: '/path/to/config.yml',
1656
1686
  maximumPreparingIssuesCount: null,
@@ -1699,6 +1729,7 @@ describe('StartPreparationUseCase', () => {
1699
1729
  projectUrl: 'https://github.com/user/repo',
1700
1730
  defaultAgentName: 'agent1',
1701
1731
  defaultLlmModelName: 'claude-sonnet-4-6',
1732
+ fallbackLlmModelName: null,
1702
1733
  defaultLlmAgentName: null,
1703
1734
  configFilePath: '/path/to/config.yml',
1704
1735
  maximumPreparingIssuesCount: null,
@@ -1753,6 +1784,7 @@ describe('StartPreparationUseCase', () => {
1753
1784
  projectUrl: 'https://github.com/user/repo',
1754
1785
  defaultAgentName: 'agent1',
1755
1786
  defaultLlmModelName: 'claude-sonnet-4-6',
1787
+ fallbackLlmModelName: null,
1756
1788
  defaultLlmAgentName: null,
1757
1789
  configFilePath: '/path/to/config.yml',
1758
1790
  maximumPreparingIssuesCount: null,
@@ -1801,6 +1833,7 @@ describe('StartPreparationUseCase', () => {
1801
1833
  projectUrl: 'https://github.com/user/repo',
1802
1834
  defaultAgentName: 'agent1',
1803
1835
  defaultLlmModelName: 'claude-sonnet-4-6',
1836
+ fallbackLlmModelName: null,
1804
1837
  defaultLlmAgentName: null,
1805
1838
  configFilePath: '/path/to/config.yml',
1806
1839
  maximumPreparingIssuesCount: null,
@@ -1847,6 +1880,7 @@ describe('StartPreparationUseCase', () => {
1847
1880
  projectUrl: 'https://github.com/user/repo',
1848
1881
  defaultAgentName: 'agent1',
1849
1882
  defaultLlmModelName: 'claude-sonnet-4-6',
1883
+ fallbackLlmModelName: null,
1850
1884
  defaultLlmAgentName: null,
1851
1885
  configFilePath: '/path/to/config.yml',
1852
1886
  maximumPreparingIssuesCount: null,
@@ -1887,6 +1921,7 @@ describe('StartPreparationUseCase', () => {
1887
1921
  projectUrl: 'https://github.com/user/repo',
1888
1922
  defaultAgentName: 'agent1',
1889
1923
  defaultLlmModelName: 'claude-sonnet-4-6',
1924
+ fallbackLlmModelName: null,
1890
1925
  defaultLlmAgentName: null,
1891
1926
  configFilePath: '/path/to/config.yml',
1892
1927
  maximumPreparingIssuesCount: null,
@@ -1924,6 +1959,7 @@ describe('StartPreparationUseCase', () => {
1924
1959
  projectUrl: 'https://github.com/user/repo',
1925
1960
  defaultAgentName: 'agent1',
1926
1961
  defaultLlmModelName: 'claude-opus',
1962
+ fallbackLlmModelName: null,
1927
1963
  defaultLlmAgentName: null,
1928
1964
  configFilePath: '/path/to/config.yml',
1929
1965
  maximumPreparingIssuesCount: null,
@@ -1972,6 +2008,7 @@ describe('StartPreparationUseCase', () => {
1972
2008
  projectUrl: 'https://github.com/user/repo',
1973
2009
  defaultAgentName: 'agent1',
1974
2010
  defaultLlmModelName: 'claude-opus',
2011
+ fallbackLlmModelName: null,
1975
2012
  defaultLlmAgentName: null,
1976
2013
  configFilePath: '/path/to/config.yml',
1977
2014
  maximumPreparingIssuesCount: null,
@@ -2020,6 +2057,7 @@ describe('StartPreparationUseCase', () => {
2020
2057
  projectUrl: 'https://github.com/user/repo',
2021
2058
  defaultAgentName: 'agent1',
2022
2059
  defaultLlmModelName: 'claude-opus',
2060
+ fallbackLlmModelName: null,
2023
2061
  defaultLlmAgentName: null,
2024
2062
  configFilePath: '/path/to/config.yml',
2025
2063
  maximumPreparingIssuesCount: null,
@@ -2088,6 +2126,7 @@ describe('StartPreparationUseCase', () => {
2088
2126
  projectUrl: 'https://github.com/user/repo',
2089
2127
  defaultAgentName: 'agent1',
2090
2128
  defaultLlmModelName: 'claude-opus',
2129
+ fallbackLlmModelName: null,
2091
2130
  defaultLlmAgentName: null,
2092
2131
  configFilePath: '/path/to/config.yml',
2093
2132
  maximumPreparingIssuesCount: null,
@@ -2153,6 +2192,7 @@ describe('StartPreparationUseCase', () => {
2153
2192
  projectUrl: 'https://github.com/user/repo',
2154
2193
  defaultAgentName: 'agent1',
2155
2194
  defaultLlmModelName: 'claude-opus',
2195
+ fallbackLlmModelName: null,
2156
2196
  defaultLlmAgentName: null,
2157
2197
  configFilePath: '/path/to/config.yml',
2158
2198
  maximumPreparingIssuesCount: null,
@@ -2212,6 +2252,7 @@ describe('StartPreparationUseCase', () => {
2212
2252
  projectUrl: 'https://github.com/user/repo',
2213
2253
  defaultAgentName: 'agent1',
2214
2254
  defaultLlmModelName: 'claude-opus',
2255
+ fallbackLlmModelName: null,
2215
2256
  defaultLlmAgentName: null,
2216
2257
  configFilePath: '/path/to/config.yml',
2217
2258
  maximumPreparingIssuesCount: null,
@@ -2240,6 +2281,7 @@ describe('StartPreparationUseCase', () => {
2240
2281
  projectUrl: 'https://github.com/user/repo',
2241
2282
  defaultAgentName: 'agent1',
2242
2283
  defaultLlmModelName: null,
2284
+ fallbackLlmModelName: null,
2243
2285
  defaultLlmAgentName: null,
2244
2286
  configFilePath: '/path/to/config.yml',
2245
2287
  maximumPreparingIssuesCount: null,
@@ -2287,6 +2329,7 @@ describe('StartPreparationUseCase', () => {
2287
2329
  projectUrl: 'https://github.com/user/repo',
2288
2330
  defaultAgentName: 'agent1',
2289
2331
  defaultLlmModelName: 'claude-sonnet-4-6',
2332
+ fallbackLlmModelName: null,
2290
2333
  defaultLlmAgentName: null,
2291
2334
  configFilePath: '/path/to/config.yml',
2292
2335
  maximumPreparingIssuesCount: null,
@@ -2337,6 +2380,7 @@ describe('StartPreparationUseCase', () => {
2337
2380
  projectUrl: 'https://github.com/user/repo',
2338
2381
  defaultAgentName: 'agent1',
2339
2382
  defaultLlmModelName: 'claude-opus',
2383
+ fallbackLlmModelName: null,
2340
2384
  defaultLlmAgentName: null,
2341
2385
  configFilePath: '/path/to/config.yml',
2342
2386
  maximumPreparingIssuesCount: null,
@@ -2423,6 +2467,7 @@ describe('StartPreparationUseCase', () => {
2423
2467
  projectUrl: 'https://github.com/user/repo',
2424
2468
  defaultAgentName: 'agent1',
2425
2469
  defaultLlmModelName: 'claude-opus',
2470
+ fallbackLlmModelName: null,
2426
2471
  defaultLlmAgentName: null,
2427
2472
  configFilePath: '/path/to/config.yml',
2428
2473
  maximumPreparingIssuesCount: null,
@@ -2480,6 +2525,7 @@ describe('StartPreparationUseCase', () => {
2480
2525
  projectUrl: 'https://github.com/user/repo',
2481
2526
  defaultAgentName: 'agent1',
2482
2527
  defaultLlmModelName: 'claude-opus',
2528
+ fallbackLlmModelName: null,
2483
2529
  defaultLlmAgentName: null,
2484
2530
  configFilePath: '/path/to/config.yml',
2485
2531
  maximumPreparingIssuesCount: null,
@@ -2551,6 +2597,7 @@ describe('StartPreparationUseCase', () => {
2551
2597
  projectUrl: 'https://github.com/user/repo',
2552
2598
  defaultAgentName: 'agent1',
2553
2599
  defaultLlmModelName: 'claude-opus',
2600
+ fallbackLlmModelName: null,
2554
2601
  defaultLlmAgentName: null,
2555
2602
  configFilePath: '/path/to/config.yml',
2556
2603
  maximumPreparingIssuesCount: null,
@@ -2634,6 +2681,7 @@ describe('StartPreparationUseCase', () => {
2634
2681
  projectUrl: 'https://github.com/user/repo',
2635
2682
  defaultAgentName: 'agent1',
2636
2683
  defaultLlmModelName: 'claude-opus',
2684
+ fallbackLlmModelName: null,
2637
2685
  defaultLlmAgentName: null,
2638
2686
  configFilePath: '/path/to/config.yml',
2639
2687
  maximumPreparingIssuesCount: null,
@@ -2696,6 +2744,7 @@ describe('StartPreparationUseCase', () => {
2696
2744
  projectUrl: 'https://github.com/user/repo',
2697
2745
  defaultAgentName: 'agent1',
2698
2746
  defaultLlmModelName: 'claude-opus',
2747
+ fallbackLlmModelName: null,
2699
2748
  defaultLlmAgentName: null,
2700
2749
  configFilePath: '/path/to/config.yml',
2701
2750
  maximumPreparingIssuesCount: null,
@@ -2761,6 +2810,7 @@ describe('StartPreparationUseCase', () => {
2761
2810
  projectUrl: 'https://github.com/user/repo',
2762
2811
  defaultAgentName: 'agent1',
2763
2812
  defaultLlmModelName: 'claude-opus',
2813
+ fallbackLlmModelName: null,
2764
2814
  defaultLlmAgentName: null,
2765
2815
  configFilePath: '/path/to/config.yml',
2766
2816
  maximumPreparingIssuesCount: null,
@@ -2829,6 +2879,7 @@ describe('StartPreparationUseCase', () => {
2829
2879
  projectUrl: 'https://github.com/user/repo',
2830
2880
  defaultAgentName: 'agent1',
2831
2881
  defaultLlmModelName: 'claude-opus',
2882
+ fallbackLlmModelName: null,
2832
2883
  defaultLlmAgentName: null,
2833
2884
  configFilePath: '/path/to/config.yml',
2834
2885
  maximumPreparingIssuesCount: null,
@@ -2937,6 +2988,7 @@ describe('StartPreparationUseCase', () => {
2937
2988
  projectUrl: 'https://github.com/user/repo',
2938
2989
  defaultAgentName: 'agent1',
2939
2990
  defaultLlmModelName: 'claude-opus',
2991
+ fallbackLlmModelName: null,
2940
2992
  defaultLlmAgentName: null,
2941
2993
  configFilePath: '/path/to/config.yml',
2942
2994
  maximumPreparingIssuesCount: null,
@@ -2995,6 +3047,7 @@ describe('StartPreparationUseCase', () => {
2995
3047
  projectUrl: 'https://github.com/user/repo',
2996
3048
  defaultAgentName: 'agent1',
2997
3049
  defaultLlmModelName: 'claude-opus',
3050
+ fallbackLlmModelName: null,
2998
3051
  defaultLlmAgentName: null,
2999
3052
  configFilePath: '/path/to/config.yml',
3000
3053
  maximumPreparingIssuesCount: null,
@@ -3057,6 +3110,7 @@ describe('StartPreparationUseCase', () => {
3057
3110
  projectUrl: 'https://github.com/user/repo',
3058
3111
  defaultAgentName: 'agent1',
3059
3112
  defaultLlmModelName: 'claude-opus',
3113
+ fallbackLlmModelName: null,
3060
3114
  defaultLlmAgentName: null,
3061
3115
  configFilePath: '/path/to/config.yml',
3062
3116
  maximumPreparingIssuesCount: null,
@@ -3119,6 +3173,7 @@ describe('StartPreparationUseCase', () => {
3119
3173
  projectUrl: 'https://github.com/user/repo',
3120
3174
  defaultAgentName: 'agent1',
3121
3175
  defaultLlmModelName: 'claude-opus',
3176
+ fallbackLlmModelName: null,
3122
3177
  defaultLlmAgentName: null,
3123
3178
  configFilePath: '/path/to/config.yml',
3124
3179
  maximumPreparingIssuesCount: null,
@@ -3181,6 +3236,7 @@ describe('StartPreparationUseCase', () => {
3181
3236
  projectUrl: 'https://github.com/user/repo',
3182
3237
  defaultAgentName: 'agent1',
3183
3238
  defaultLlmModelName: 'claude-opus',
3239
+ fallbackLlmModelName: null,
3184
3240
  defaultLlmAgentName: null,
3185
3241
  configFilePath: '/path/to/config.yml',
3186
3242
  maximumPreparingIssuesCount: null,
@@ -3246,6 +3302,7 @@ describe('StartPreparationUseCase', () => {
3246
3302
  projectUrl: 'https://github.com/user/repo',
3247
3303
  defaultAgentName: 'agent1',
3248
3304
  defaultLlmModelName: 'claude-opus',
3305
+ fallbackLlmModelName: null,
3249
3306
  defaultLlmAgentName: null,
3250
3307
  configFilePath: '/path/to/config.yml',
3251
3308
  maximumPreparingIssuesCount: null,
@@ -3293,6 +3350,7 @@ describe('StartPreparationUseCase', () => {
3293
3350
  projectUrl: 'https://github.com/user/repo',
3294
3351
  defaultAgentName: 'agent1',
3295
3352
  defaultLlmModelName: 'claude-opus',
3353
+ fallbackLlmModelName: null,
3296
3354
  defaultLlmAgentName: null,
3297
3355
  configFilePath: '/path/to/config.yml',
3298
3356
  maximumPreparingIssuesCount: null,
@@ -3358,6 +3416,7 @@ describe('StartPreparationUseCase', () => {
3358
3416
  projectUrl: 'https://github.com/user/repo',
3359
3417
  defaultAgentName: 'agent1',
3360
3418
  defaultLlmModelName: 'claude-sonnet-4-6',
3419
+ fallbackLlmModelName: null,
3361
3420
  defaultLlmAgentName: null,
3362
3421
  configFilePath: '/path/to/config.yml',
3363
3422
  maximumPreparingIssuesCount: null,
@@ -3423,6 +3482,7 @@ describe('StartPreparationUseCase', () => {
3423
3482
  projectUrl: 'https://github.com/user/repo',
3424
3483
  defaultAgentName: 'agent1',
3425
3484
  defaultLlmModelName: 'claude-sonnet-4-6',
3485
+ fallbackLlmModelName: null,
3426
3486
  defaultLlmAgentName: null,
3427
3487
  configFilePath: '/path/to/config.yml',
3428
3488
  maximumPreparingIssuesCount: null,
@@ -3488,6 +3548,7 @@ describe('StartPreparationUseCase', () => {
3488
3548
  projectUrl: 'https://github.com/user/repo',
3489
3549
  defaultAgentName: 'agent1',
3490
3550
  defaultLlmModelName: 'claude-opus',
3551
+ fallbackLlmModelName: null,
3491
3552
  defaultLlmAgentName: null,
3492
3553
  configFilePath: '/path/to/config.yml',
3493
3554
  maximumPreparingIssuesCount: null,
@@ -3553,6 +3614,7 @@ describe('StartPreparationUseCase', () => {
3553
3614
  projectUrl: 'https://github.com/user/repo',
3554
3615
  defaultAgentName: 'agent1',
3555
3616
  defaultLlmModelName: 'claude-opus',
3617
+ fallbackLlmModelName: null,
3556
3618
  defaultLlmAgentName: null,
3557
3619
  configFilePath: '/path/to/config.yml',
3558
3620
  maximumPreparingIssuesCount: null,
@@ -3626,6 +3688,7 @@ describe('StartPreparationUseCase', () => {
3626
3688
  projectUrl: 'https://github.com/user/repo',
3627
3689
  defaultAgentName: 'agent1',
3628
3690
  defaultLlmModelName: 'claude-opus',
3691
+ fallbackLlmModelName: null,
3629
3692
  defaultLlmAgentName: null,
3630
3693
  configFilePath: '/path/to/config.yml',
3631
3694
  maximumPreparingIssuesCount: null,
@@ -3699,6 +3762,7 @@ describe('StartPreparationUseCase', () => {
3699
3762
  projectUrl: 'https://github.com/user/repo',
3700
3763
  defaultAgentName: 'agent1',
3701
3764
  defaultLlmModelName: 'claude-opus',
3765
+ fallbackLlmModelName: null,
3702
3766
  defaultLlmAgentName: null,
3703
3767
  configFilePath: '/path/to/config.yml',
3704
3768
  maximumPreparingIssuesCount: null,
@@ -3777,6 +3841,7 @@ describe('StartPreparationUseCase', () => {
3777
3841
  projectUrl: 'https://github.com/user/repo',
3778
3842
  defaultAgentName: 'agent1',
3779
3843
  defaultLlmModelName: 'claude-opus',
3844
+ fallbackLlmModelName: null,
3780
3845
  defaultLlmAgentName: null,
3781
3846
  configFilePath: '/path/to/config.yml',
3782
3847
  maximumPreparingIssuesCount: null,
@@ -3882,6 +3947,7 @@ describe('StartPreparationUseCase', () => {
3882
3947
  projectUrl: 'https://github.com/user/repo',
3883
3948
  defaultAgentName: 'agent1',
3884
3949
  defaultLlmModelName: 'claude-opus',
3950
+ fallbackLlmModelName: null,
3885
3951
  defaultLlmAgentName: null,
3886
3952
  configFilePath: '/path/to/config.yml',
3887
3953
  maximumPreparingIssuesCount: null,
@@ -3953,6 +4019,7 @@ describe('StartPreparationUseCase', () => {
3953
4019
  projectUrl: 'https://github.com/user/repo',
3954
4020
  defaultAgentName: 'agent1',
3955
4021
  defaultLlmModelName: 'claude-opus',
4022
+ fallbackLlmModelName: null,
3956
4023
  defaultLlmAgentName: null,
3957
4024
  configFilePath: '/path/to/config.yml',
3958
4025
  maximumPreparingIssuesCount: null,
@@ -4021,6 +4088,7 @@ describe('StartPreparationUseCase', () => {
4021
4088
  projectUrl: 'https://github.com/user/repo',
4022
4089
  defaultAgentName: 'agent1',
4023
4090
  defaultLlmModelName: 'claude-opus',
4091
+ fallbackLlmModelName: null,
4024
4092
  defaultLlmAgentName: null,
4025
4093
  configFilePath: '/path/to/config.yml',
4026
4094
  maximumPreparingIssuesCount: null,
@@ -4068,6 +4136,7 @@ describe('StartPreparationUseCase', () => {
4068
4136
  projectUrl: 'https://github.com/user/repo',
4069
4137
  defaultAgentName: params.defaultAgentName,
4070
4138
  defaultLlmModelName: 'claude-opus',
4139
+ fallbackLlmModelName: null,
4071
4140
  defaultLlmAgentName: params.defaultLlmAgentName,
4072
4141
  configFilePath: '/path/to/config.yml',
4073
4142
  maximumPreparingIssuesCount: null,
@@ -4172,6 +4241,346 @@ describe('StartPreparationUseCase', () => {
4172
4241
  expect(selectedAgent).toBe('impl');
4173
4242
  });
4174
4243
  });
4244
+
4245
+ describe('Sonnet-to-Opus weekly limit fallback', () => {
4246
+ const futureReset = Math.floor(Date.now() / 1000) + 3600;
4247
+
4248
+ it('spawns preparations with the Opus fallback model when the sonnet default is selected and every token has its seven_day_sonnet weekly limit exhausted while opus capacity remains', async () => {
4249
+ const awaitingIssue = createMockIssue({
4250
+ url: 'url1',
4251
+ title: 'Issue 1',
4252
+ labels: ['category:impl'],
4253
+ status: 'Awaiting Workspace',
4254
+ number: 1,
4255
+ itemId: 'item-1',
4256
+ });
4257
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
4258
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
4259
+ createMockStoryObjectMap([awaitingIssue]),
4260
+ );
4261
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
4262
+ stdout: '',
4263
+ stderr: '',
4264
+ exitCode: 0,
4265
+ });
4266
+ mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
4267
+ {
4268
+ name: 'token-sonnet-exhausted',
4269
+ token: 'token-sonnet-exhausted',
4270
+ fiveHourUtilization: 0.1,
4271
+ sevenDayUtilization: 0,
4272
+ blocked: false,
4273
+ rejected: false,
4274
+ modelWeeklyLimits: {
4275
+ seven_day_sonnet: { rejected: true, resetsAt: futureReset },
4276
+ },
4277
+ },
4278
+ ]);
4279
+
4280
+ await useCase.run({
4281
+ projectUrl: 'https://github.com/user/repo',
4282
+ defaultAgentName: 'agent1',
4283
+ defaultLlmModelName: 'claude-sonnet-4-6',
4284
+ fallbackLlmModelName: null,
4285
+ defaultLlmAgentName: null,
4286
+ configFilePath: '/path/to/config.yml',
4287
+ maximumPreparingIssuesCount: null,
4288
+ utilizationPercentageThreshold: 90,
4289
+ allowedIssueAuthors: null,
4290
+ codexHomeCandidates: null,
4291
+ allowIssueCacheMinutes: 0,
4292
+ labelsAsLlmAgentName: null,
4293
+ });
4294
+
4295
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
4296
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
4297
+ 'url1',
4298
+ 'impl',
4299
+ 'claude-opus-4-8',
4300
+ '--configFilePath',
4301
+ '/path/to/config.yml',
4302
+ '--branch',
4303
+ 'i1',
4304
+ ]);
4305
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
4306
+ env: {
4307
+ CLAUDE_CODE_OAUTH_TOKEN: 'token-sonnet-exhausted',
4308
+ ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
4309
+ },
4310
+ });
4311
+ });
4312
+
4313
+ it('uses the configured fallbackLlmModelName instead of the default when falling back to opus', async () => {
4314
+ const awaitingIssue = createMockIssue({
4315
+ url: 'url1',
4316
+ title: 'Issue 1',
4317
+ labels: ['category:impl'],
4318
+ status: 'Awaiting Workspace',
4319
+ number: 1,
4320
+ itemId: 'item-1',
4321
+ });
4322
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
4323
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
4324
+ createMockStoryObjectMap([awaitingIssue]),
4325
+ );
4326
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
4327
+ stdout: '',
4328
+ stderr: '',
4329
+ exitCode: 0,
4330
+ });
4331
+ mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
4332
+ {
4333
+ name: 'token-sonnet-exhausted',
4334
+ token: 'token-sonnet-exhausted',
4335
+ fiveHourUtilization: 0.1,
4336
+ sevenDayUtilization: 0,
4337
+ blocked: false,
4338
+ rejected: false,
4339
+ modelWeeklyLimits: {
4340
+ seven_day_sonnet: { rejected: true, resetsAt: futureReset },
4341
+ },
4342
+ },
4343
+ ]);
4344
+
4345
+ await useCase.run({
4346
+ projectUrl: 'https://github.com/user/repo',
4347
+ defaultAgentName: 'agent1',
4348
+ defaultLlmModelName: 'claude-sonnet-4-6',
4349
+ fallbackLlmModelName: 'claude-opus-4-8',
4350
+ defaultLlmAgentName: null,
4351
+ configFilePath: '/path/to/config.yml',
4352
+ maximumPreparingIssuesCount: null,
4353
+ utilizationPercentageThreshold: 90,
4354
+ allowedIssueAuthors: null,
4355
+ codexHomeCandidates: null,
4356
+ allowIssueCacheMinutes: 0,
4357
+ labelsAsLlmAgentName: null,
4358
+ });
4359
+
4360
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
4361
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
4362
+ 'claude-opus-4-8',
4363
+ );
4364
+ });
4365
+
4366
+ it('skips preparation when the sonnet default is exhausted and the opus fallback is also exhausted via the generic seven_day weekly limit', async () => {
4367
+ const awaitingIssue = createMockIssue({
4368
+ url: 'url1',
4369
+ title: 'Issue 1',
4370
+ labels: ['category:impl'],
4371
+ status: 'Awaiting Workspace',
4372
+ number: 1,
4373
+ itemId: 'item-1',
4374
+ });
4375
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
4376
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
4377
+ createMockStoryObjectMap([awaitingIssue]),
4378
+ );
4379
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
4380
+ stdout: '',
4381
+ stderr: '',
4382
+ exitCode: 0,
4383
+ });
4384
+ mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
4385
+ {
4386
+ name: 'token-fully-exhausted',
4387
+ token: 'token-fully-exhausted',
4388
+ fiveHourUtilization: 0.1,
4389
+ sevenDayUtilization: 0,
4390
+ blocked: false,
4391
+ rejected: false,
4392
+ modelWeeklyLimits: {
4393
+ seven_day_sonnet: { rejected: true, resetsAt: futureReset },
4394
+ seven_day: { rejected: true, resetsAt: futureReset },
4395
+ },
4396
+ },
4397
+ ]);
4398
+ const consoleWarnSpy = jest
4399
+ .spyOn(console, 'warn')
4400
+ .mockImplementation(() => {});
4401
+
4402
+ await useCase.run({
4403
+ projectUrl: 'https://github.com/user/repo',
4404
+ defaultAgentName: 'agent1',
4405
+ defaultLlmModelName: 'claude-sonnet-4-6',
4406
+ fallbackLlmModelName: null,
4407
+ defaultLlmAgentName: null,
4408
+ configFilePath: '/path/to/config.yml',
4409
+ maximumPreparingIssuesCount: null,
4410
+ utilizationPercentageThreshold: 90,
4411
+ allowedIssueAuthors: null,
4412
+ codexHomeCandidates: null,
4413
+ allowIssueCacheMinutes: 0,
4414
+ labelsAsLlmAgentName: null,
4415
+ });
4416
+
4417
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
4418
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
4419
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
4420
+ expect.stringContaining('Skipping starting preparation'),
4421
+ );
4422
+ consoleWarnSpy.mockRestore();
4423
+ });
4424
+
4425
+ it('uses the sonnet default with no fallback when sonnet tokens are available', async () => {
4426
+ const awaitingIssue = createMockIssue({
4427
+ url: 'url1',
4428
+ title: 'Issue 1',
4429
+ labels: ['category:impl'],
4430
+ status: 'Awaiting Workspace',
4431
+ number: 1,
4432
+ itemId: 'item-1',
4433
+ });
4434
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
4435
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
4436
+ createMockStoryObjectMap([awaitingIssue]),
4437
+ );
4438
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
4439
+ stdout: '',
4440
+ stderr: '',
4441
+ exitCode: 0,
4442
+ });
4443
+ mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
4444
+ {
4445
+ name: 'token-ok',
4446
+ token: 'token-ok',
4447
+ fiveHourUtilization: 0.1,
4448
+ sevenDayUtilization: 0,
4449
+ blocked: false,
4450
+ rejected: false,
4451
+ modelWeeklyLimits: {},
4452
+ },
4453
+ ]);
4454
+
4455
+ await useCase.run({
4456
+ projectUrl: 'https://github.com/user/repo',
4457
+ defaultAgentName: 'agent1',
4458
+ defaultLlmModelName: 'claude-sonnet-4-6',
4459
+ fallbackLlmModelName: null,
4460
+ defaultLlmAgentName: null,
4461
+ configFilePath: '/path/to/config.yml',
4462
+ maximumPreparingIssuesCount: null,
4463
+ utilizationPercentageThreshold: 90,
4464
+ allowedIssueAuthors: null,
4465
+ codexHomeCandidates: null,
4466
+ allowIssueCacheMinutes: 0,
4467
+ labelsAsLlmAgentName: null,
4468
+ });
4469
+
4470
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
4471
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
4472
+ 'claude-sonnet-4-6',
4473
+ );
4474
+ });
4475
+
4476
+ it('does not fall back to opus for an issue whose llm-model label explicitly set the model even when the sonnet weekly limit is exhausted', async () => {
4477
+ const awaitingIssue = createMockIssue({
4478
+ url: 'url1',
4479
+ title: 'Issue 1',
4480
+ labels: ['category:impl', 'llm-model:claude-sonnet-4-6'],
4481
+ status: 'Awaiting Workspace',
4482
+ number: 1,
4483
+ itemId: 'item-1',
4484
+ });
4485
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
4486
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
4487
+ createMockStoryObjectMap([awaitingIssue]),
4488
+ );
4489
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
4490
+ stdout: '',
4491
+ stderr: '',
4492
+ exitCode: 0,
4493
+ });
4494
+ mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
4495
+ {
4496
+ name: 'token-sonnet-exhausted',
4497
+ token: 'token-sonnet-exhausted',
4498
+ fiveHourUtilization: 0.1,
4499
+ sevenDayUtilization: 0,
4500
+ blocked: false,
4501
+ rejected: false,
4502
+ modelWeeklyLimits: {
4503
+ seven_day_sonnet: { rejected: true, resetsAt: futureReset },
4504
+ },
4505
+ },
4506
+ ]);
4507
+
4508
+ await useCase.run({
4509
+ projectUrl: 'https://github.com/user/repo',
4510
+ defaultAgentName: 'agent1',
4511
+ defaultLlmModelName: 'claude-sonnet-4-6',
4512
+ fallbackLlmModelName: null,
4513
+ defaultLlmAgentName: null,
4514
+ configFilePath: '/path/to/config.yml',
4515
+ maximumPreparingIssuesCount: null,
4516
+ utilizationPercentageThreshold: 90,
4517
+ allowedIssueAuthors: null,
4518
+ codexHomeCandidates: null,
4519
+ allowIssueCacheMinutes: 0,
4520
+ labelsAsLlmAgentName: null,
4521
+ });
4522
+
4523
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
4524
+ expect(mockLocalCommandRunner.runCommand.mock.calls[0][1][2]).toBe(
4525
+ 'claude-sonnet-4-6',
4526
+ );
4527
+ });
4528
+
4529
+ it('does not fall back to opus when sonnet tokens are merely throttled by 5-hour utilization rather than the weekly limit', async () => {
4530
+ const awaitingIssue = createMockIssue({
4531
+ url: 'url1',
4532
+ title: 'Issue 1',
4533
+ labels: ['category:impl'],
4534
+ status: 'Awaiting Workspace',
4535
+ number: 1,
4536
+ itemId: 'item-1',
4537
+ });
4538
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
4539
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
4540
+ createMockStoryObjectMap([awaitingIssue]),
4541
+ );
4542
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
4543
+ stdout: '',
4544
+ stderr: '',
4545
+ exitCode: 0,
4546
+ });
4547
+ mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
4548
+ {
4549
+ name: 'token-throttled',
4550
+ token: 'token-throttled',
4551
+ fiveHourUtilization: 0.95,
4552
+ sevenDayUtilization: 0,
4553
+ blocked: false,
4554
+ rejected: false,
4555
+ modelWeeklyLimits: {},
4556
+ },
4557
+ ]);
4558
+ const consoleWarnSpy = jest
4559
+ .spyOn(console, 'warn')
4560
+ .mockImplementation(() => {});
4561
+
4562
+ await useCase.run({
4563
+ projectUrl: 'https://github.com/user/repo',
4564
+ defaultAgentName: 'agent1',
4565
+ defaultLlmModelName: 'claude-sonnet-4-6',
4566
+ fallbackLlmModelName: null,
4567
+ defaultLlmAgentName: null,
4568
+ configFilePath: '/path/to/config.yml',
4569
+ maximumPreparingIssuesCount: null,
4570
+ utilizationPercentageThreshold: 90,
4571
+ allowedIssueAuthors: null,
4572
+ codexHomeCandidates: null,
4573
+ allowIssueCacheMinutes: 0,
4574
+ labelsAsLlmAgentName: null,
4575
+ });
4576
+
4577
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
4578
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
4579
+ expect.stringContaining('Skipping starting preparation'),
4580
+ );
4581
+ consoleWarnSpy.mockRestore();
4582
+ });
4583
+ });
4175
4584
  });
4176
4585
 
4177
4586
  describe('StartPreparationUseCase.buildRotationOrder', () => {